Я делаю этот вид вещи время от времени, и интересно, является ли это запах дизайна, или если существует лучший шаблон разработки, который я могу использовать.
Существует процесс со многими шагами, который известен во время компиляции, но, вероятно, изменится в будущем. Я получаю общность в абстрактном классе Шага, пишу StepLister, который возвращает список шагов, один для каждого производного класса Шага, и затем StepsRunner, который называет StepLister, затем выполняет итерации по списку и выполняет каждый шаг. Иногда один шаг будет зависеть от результата предыдущего шага, иногда нет.
Какие-либо предложения?
Я не уверен, что правильно понял вопрос, но поскольку вы выполняете шаги последовательно, я предположу, что сохраняется некоторая контекстная информация, и таким образом вы говорите о выборе следующего шага на основе результата текущего.
Это, собственно, и есть суть автомата. У вас есть различные состояния, связанные между собой переходами.
Довольно легко попросить каждый шаг вернуть некоторый тег
, возможно, просто строку или подходящим образом определенный тип.
Затем вы определяете автомат, определяя следующий шаг для каждого из возможных выходов текущего шага.
Например, я использую фреймворк (на работе), который принимает эти переходы в виде xml
файла... хотя мне очень не нравится тот факт, что в нем практически не проверяется, правильно ли определены переходы.
Обратите внимание, что в C++ это можно проверить во время компиляции (я думаю использовать Boost.Variant
и некоторые трюки программирования меташаблонов).
Ваш подход кажется мне разумным (комбинация итераторов / стратегий).
Иногда один шаг будет зависеть от результата предыдущего шага, иногда нет.
Это может быть интересно. Поскольку я не знаю, что конкретно должен делать каждый шаг, я не могу дать ничего, кроме очень общих идей.
Зависимости между всеми шагами можно смоделировать с помощью синтаксического дерева , подобного интерпретатору , вместо того, чтобы выполнять последовательные шаги, которые вы выполняете. Таким образом, ваш StepRunner
будет отброшен в пользу методов контекста / интерпретации.
Другой идеей может быть использование монад , которые позволяют вам последовательно склеивать шаги вместе, но я не знаю, насколько легко это интегрирует вашу существующую объектно-ориентированную концепцию (поскольку обычно используются монады в функциональном программировании).
Может быть, вам вообще не нужно (чрезмерно) усложнять;)