2017-01-04 2 views
1

У меня есть класс (позволяет называть его checker) и различные классы, которые выполняют задачи (позволяют называть их задачами). каждая задача относится к нескольким категориям:разделение задач на категории

каждая задача запускается и в какой-то момент спрашивает чекер, если им разрешено что-то делать. контрольные ответы в соответствии с состоянием системы и в соответствии с их категорией. задача может быть в нескольких категориях

как бы вы это реализовали? (cpp, но я действительно не думаю, что его язык специфичен).

Я думал о добавлении списка категорий в каждой задаче и функции, которая получает категорию и ответы, если задача принадлежит ей.

class checker { 
    bool is_allowed(Task * task); 
} 

class Task 
{ 
    bool is_belongging_to_category(Category cat); 
    void some_task_to_do() 
    { 
     ... 
     if (checker::is_allowed(this)) { ....} 
     else {....} 
    } 
} 

Есть ли лучший способ решить эту проблему? Возможно, некоторые известные образцы дизайна ...

+0

Я подозреваю, что вам нужно будет предоставить более подробную информацию ... это 'is_allowed()' check, предназначенное для того, чтобы быть «мне разрешено делать эту специфическую вещь» (например, какая-то модель «разрешений»), потому что если поэтому, что вы показали, не имеет никаких указаний о том, что именно задает задача. В качестве альтернативы, это общий «мне разрешено выполнять какую-либо работу [любого вида]» (т. Е. Больше модели «балансировки нагрузки»)? Если последнее, вероятно, должно быть некоторое время/цикл сна или другой механизм планирования. – TripeHound

+0

is_allowed - это разрешение mechanisem. Я не хотел усложнять ситуацию, но это часть гораздо более крупной системы, и задачи - это способ парализовать работу. например, задача может захотеть сохранить ее конфигурацию на диск, но это не разрешено, если система находится во время выключения (если эта задача не является частью выключения) – Epic

ответ

0

это выглядит как сомнительный дизайн. Вы делаете задачи объектами.

Допустим, ваши задачи: Ешьте, напитка и Be_Merry

Если вы делаете каждый из этих задач объектов, они должны поддерживать ссылку на реальное лицо, что они работают on, то при выполнении условия они должны будут изменить состояние для данного человека.

Это нарушение Object Oriented Design, который определяет объект как:

тесная связь или объединение структур данных с методами или функциями, которые действуют на данных

Обратите внимание, что у вас есть разделять «методы или функции, которые действуют на данные» с объекта. Вместо этого вы должны были смоделированы объекты Джек и Джилл которые были методы: Ешьте, Пейте и BeMerry

Насколько checker, будь то поделен будет зависеть от того, вам используя push или pull coding. Если вы делаете нажимное кодирование, то шашка просто удерживающая область для поведенческих свойств Джека и Джилл, в таком случае свойство должно быть прижато к Джеку и Джилл, а не проводится в checker , Если они являются объектами недвижимости для всех Jack или Jill объектов, используйте static. Если, однако, вы используете кодировку pull, информация недоступна, пока вы не попытаетесь выполнить задачу. В этом случае checker должен, вероятно, быть одиночным, что Jack и Jill Доступ в процессе выполнения своих задач.

EDIT:

Your comment показывает дальнейшую трагедию в дизайне. Кажется, что вы начали кучу потоков, которые ожидают ожидание на checker. Это означает, что вам нужно использовать кодировку pull. Вы Джек и Джилл объектов должны поддерживать булевы, для каких задач они активно участвует, например m_is_going_to_school, а затем, когда checker получает условие, что бы остановить ваше ожидание занято в дизайне, а не пнуть метод goToSchool ,

+0

Объект Task имеет метод и что бы установить эти m_canEat и т. д. чем вызов булевой функции, как в вопросе? Могут быть случаи, когда can может быть нажата, а не запрашивается, но вы не можете утверждать, что из информации в вопросе - вполне может быть «обратиться к внешнему checker " – ROX

+0

@ROX" Что бы установить эти m_canEat и т. д., кроме вызова булевой функции, как в вопросе?«Вместо того, чтобы отделять информацию о том, как * Jack * или * Jill * должны функционировать в этих объектах и' checker', вы будете хранить их в * Jack * или * Jill *, если логическое поведение управляет поведением всех таких объектов, сделайте его статическим членом. Что касается случая вытяжной системы, вы правы, поэтому я отредактирую. –

+0

технически говоря, что вы правы (и я дал вам +1), но это часть большого система и классы задач - это способ распараллеливать длинные задачи. Например, у jill может быть задача «идти в школу», которая длинна и построена из нескольких подфаз, поэтому в этой реализации будет задача go_to_school с указателем чтобы выполнить эту задачу в параллельном механизме, которым управляет система. – Epic

0

Вы можете сделать вектор для хранения всех возможных разрешенных опций. Вы можете сделать функцию bool (как и у вас) с именем IsAllowed с строкой аргумента, и она будет проверять, разрешен ли этот параметр. Если нет, верните false. Это только моя идея. Конечно, есть два миллиона способов реализации этого. Если вы хотите несколько вариантов. Затем вы можете сделать 2d-вектор и посмотреть, имеет ли соответствующая строка какие-либо параметры. Удачи!

0

Если вы знаете максимальное количество категорий заранее, я бы рекомендовал использовать бит-флаги для этого.

enum Category { 
    CATEGORY_A = 1, 
    CATEGORY_B = 1 << 1, 
    CATEGORY_C = 1 << 2, 
    CATEGORY_D = 1 << 3, 
}; 

class Task { 
    int32_t categories_; 
public: 
    Task() : categories_(0) {} 

    void add_category(Category cat) { 
    categories_ |= cat; 
    } 

    void run() { 
    checker::can_run(categories_); 
    } 
} 

Это позволяет проверить несколько категорий сразу:

namespace checker { 

bool can_run(int32_t categories) { 
    int32_t cannot_run_right_now = CATEGORY_A | CATEGORY_C; 

    if(categories & cannot_run_right_now != 0) { 
    return false; 
    } 
    ... 
} 
} 
0

Ну, это зависит. Если вы на 100% уверены, что знаете, сколько категорий должно быть, и это не какой-то гигантский номер, вы можете сохранить эту информацию как целое. Если n-й бит равен 1, то задача принадлежит n-й категории. Затем зависит от состояния системы, вы можете создать другое целое число, которое будет служить в качестве маски. В конце вы просто выполните бит-И (маска & категорий! = 0), чтобы определить, поддерживает ли общий ресурс задачи и маски.

С другой стороны, если будет неизвестное количество категорий, вы можете просто составить список категорий, к которым он принадлежит. Составьте словарь [SYSTEM_STATE] => [CATEGORIES_AVAILABLE] и проверить

bool is_allowed(Task * task){ 
    foreach (Category sysC in stateCategories[sys.GetState()]) 
    { 
     foreach (Category taskC in task.GetCategories()) 
     { 
     if(sysC == taskC) return true; 
     } 
    } 
    return false; 
    } 

Это было бы, конечно, быть медленным для большого количества категорий. Вы могли бы улучшить этот метод, сделав этот список категорий некоторых другой структуры данных, в которой поиск не O (п), что код будет выглядеть следующим образом:

bool is_allowed(Task * task){ 
    foreach (Category sysC in stateCategories[sys.GetState()]) 
    { 
     if task.GetCategories().Contains(sysC) { 
     return true; 
     } 
    } 

Это зависит