Принятие решений, сложные условия и планирование простота обслуживания

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

Я собираюсь попытаться быть более конкретным с примером здесь:

Допустим, я пытаюсь управлять командой поваров-кулинаров на кухне ресторана.

Каждый шеф-повар знает, как готовить 3 вида пирогов: яблочный, тыквенный и малиновый, а также 2 вида пиццы: сырная пицца и беконная пицца. Они все умеют все готовить.

Теперь я хотел бы отправить распоряжения этим начальникам о том, что будет с клиентами.

Условия:

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

Я могу попросить шеф-повара приготовить до 5 пицц за раз, учитывая, что это для разных клиентов.

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

Я работаю с C ++.
Я мог бы написать простую инструкцию switch / case, но обслуживание было бы нелегким, если бы изменились условия или были добавлены новые пироги, и так …

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

Как бы вы справились со сложной реализацией алгоритма принятия решений?

4

Решение

Я мог бы написать простую инструкцию switch / case, но обслуживание было бы нелегким, если бы изменились условия или были добавлены новые пироги, и так …

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

Как бы вы справились со сложной реализацией алгоритма принятия решений?

Классическое изменение / рефакторинг от переключателя / случая к поддерживаемому ООП состоит в замене каждого условия и действия на специализацию / реализацию абстрактного класса.

Старый код:

variable_t variable; // initialized elsewhere
switch(variable) {
case value1:
do_action1();
break;
case value2:
do_action2();
break;
// ...
}

Новый код:

struct Actor // actor is your "abstract chef"{
virtual ~Actor();
virtual bool matches(variable_t const v) const = 0;
virtual void do_action() = 0;
};

Теперь для каждой комбинации действия и условия вы создаете одну специализацию:

struct SweedishChef: public Actor {
bool matches(variable_t const v) const override
{
return v == 1;
}

void do_action() override
{
std::cerr << "bork! bork!\n";
}
};

При этом в клиентском коде больше нет ничего закодированного.

Инициализация клиентского кода:

std::vector<std::unique_ptr<Actor>> actors;
actors.emplace_back( new SweedishChef{} };
// adding a new type of chef simply means adding _one_ line of
// code here, for the new type

Код принятия решений (замена старого switch код):

// using std::find, begin, end
variable_t variable; // initialized elsewhere
const auto chef = find(begin(actors), end(actors),
[&v](const std::unique_ptr<Actor>& a) { return a->matches(v); });

if(chef != end(actors))
chef->do_action();
else
{
// here goes whatever was in the default part of the switch code
}

С точки зрения обслуживания и тестируемости, этот код намного проще в обслуживании:

  • Изменения в коде клиента минимальны при добавлении нового шеф-повара

  • взаимодействие между шеф-поварами и командами было оформлено (и заморожено) за интерфейсом

  • каждое условие / действие может (и должно быть) проверено отдельно

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

  • механизм инициализации можно протестировать отдельно

4

Другие решения

Нет, это слишком много, чтобы закодировать. Просто посчитайте символы. Этот вид кодирования не гарантирует освобождение свободной памяти для «нового SweedishChef {}». И размер клиента стал длиннее в объявлении переменной.

-1

По вопросам рекламы [email protected]