У меня есть метод, который в основном длинный список 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
s Я создал массив указателей на функции, извлек if
тела в конкретные функции и в основном посмотреть, есть ли в массиве элемент для данного current
и выполнить функцию (в качестве побочного эффекта это немного уменьшило скорость выполнения и в значительной степени уменьшило читаемость).
Краткий пример
список команд:
1 — еда
2 — напиток
3 — иди домой
4 — тепло
5 — холодный
6 — мясо
7 — помидор
так: 1 4 6
— достанет мне мясо на гриле (или хотя бы в соответствии с реализацией приложения)
а также 2 7
— даст мне томатный сок …
а также 3
— выход.
Редактировать: switch
— case
конструкция не всегда может быть использована в этом сценарии, так как иногда current
проверяется на возвращаемое значение функции.
Итак, вопрос: меня интересует, какие другие методы вы бы использовали для решения этой проблемы.
Вы можете использовать что-то похожее на 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]))();
}
Это выглядит как дерево решений — вы можете инициализировать это дерево всеми возможными комбинациями с результатами, а затем написать один цикл, который ищет входную комбинацию и возвращает результат. Результатом может быть строка или команда (как предложено в другом ответе)
Основываясь на вашем ответе на комментарии, я думаю, что вы должны изменить свою «парадигму» и преобразовать структуру массива в кортеж или объект со значимыми атрибутами.
Дело в том, что, похоже, не все «пути выполнения» требуют одинакового количества параметров, но инкапсуляция ОО должна помочь вам справиться с этим.
Таким образом, вы должны решить проблему в начале координат, где генерируется массив.
Если это невозможно, потому что это библиотека или код, который вы не можете изменить по какой-либо причине, вы должны написать адаптер, чтобы вы могли правильно обрабатывать вещи.
Затем вы указываете в своем вопросе теги C и C ++. В зависимости от подхода, который вы хотите использовать, сообщество может предоставить более подробную информацию о конкретных решениях.
Фабричный (или фабрично-подобный) шаблон может помочь вам создать соответствующие объекты или кортежи.
Более простой подход может состоять в том, чтобы изменить сигнатуру вашего метода так, чтобы он принимал 3 параметра: действие, параметры, тип объекта, как вы указали.