Упрощение сложного метода

0

У меня есть метод, который в основном представляет собой длинный список if else с переменной глубиной (иногда довольно глубокий), поскольку он интерпретирует массив байтов и в зависимости от каждого байтового значения он делает что-то другое, например "чтение" большего от массива и снова проверяя их для некоторых значений, или он имеет прямое действие. Что-то вроде этого:

char current = array[current_index ++];
if(current == 1)
{
    char something = array[current_index ++];
    if(something == 2)
    {
         // open the fridge
    }
    else
    {
         char something_else = array[current_index ++];
         if(something_else == 3)
         {
             // make me a cake
         }
         else
         {
             // bring me a beer
         }
    }
}
else
if(current == check_this(another_variable))
{
     // so something else
}

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

Краткий пример

список команд:

1 - питание 2 - напиток 3 - домой 4 - теплый 5 - холодный 6 - мясо 7 - помидор

так что: 1 4 6 - доставит мне мясо на гриле (или, по крайней мере, по заявке), а 2 7 - даст мне томатный сок... и 3 - выход.

Edit: switch - case конструкция не всегда использовать в этом случае, так как иногда current сверяется с возвращаемым значением функции.

Итак, вопрос: я любопытно, какие другие методы вы использовали бы для атаки на эту проблему.

  • 2
    switch-case может быть?
  • 0
    Этот вопрос кажется не по теме, потому что он принадлежит codereview.SE
Показать ещё 8 комментариев
Теги:
simplify

3 ответа

2

Вы можете использовать что - то подобное Command шаблон. Создайте словарь, где ключи будут возможными значениями элементов в array а значения будут указателями на соответствующие функции, например:

{
1 = (*open_the_fridge),
2 = (*make_me_a_cake),
...
}

Затем вы можете перебрать array и выполнить соответствующие функции.

псевдокод:

func_map{1=(*open_the_fridge), 2=(*make_me_a_cake),...}
for (i = 0; i < length(array); i++) {
    (*get_value_from_dict(func_map, array[i]))();
}
0

Основываясь на вашем ответе на комментарии, я думаю, вы должны изменить свою "парадигму" и преобразовать структуру массива в кортеж или объект со значимыми атрибутами. Дело в том, что, похоже, не все "пути выполнения" потребуют одинакового количества параметров, но инкапсуляция OO должна помочь вам справиться с этим. Итак, вы должны решить проблему в источнике, где генерируется массив. Если это невозможно, потому что это библиотека или код, которые вы не можете изменить по какой-либо причине, вам следует написать адаптер, чтобы вы могли правильно обрабатывать вещи.

Затем вы указываете в своих тегах C и C++. В зависимости от подхода, который вы хотите предпринять, сообщество может предоставить более подробную информацию о конкретных решениях.

Шаблон Factory (или фабричный) может помочь вам создать соответствующие объекты или кортежи. Более простой подход может заключаться в изменении подписи вашего метода, чтобы принять 3 параметра: действие, параметры, тип объекта, как вы указали.

0

Это похоже на дерево решений - вы можете инициализировать это дерево со всей возможной комбинацией с результатами, а затем написать один цикл, который ищет комбинацию ввода и возвращает результат. Результатом может быть строка или команда (как предложено в другом ответе)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню