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

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

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
}

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

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

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

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

так: 1 4 6 — достанет мне мясо на гриле (или хотя бы в соответствии с реализацией приложения)
а также 2 7 — даст мне томатный сок …
а также 3 — выход.

Редактировать: switchcase конструкция не всегда может быть использована в этом сценарии, так как иногда current проверяется на возвращаемое значение функции.

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

0

Решение

Вы можете использовать что-то похожее на 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]))();
}
2

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

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

0

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

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

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

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