Хорошая архитектура для одного, если утверждение со многими условиями
У меня есть оператор if, который выглядит так:
if conditionA() || conditionB() || conditionC() || conditionD() || conditionE() || condition()
#do sth
end
#conditionX() methods return true/false
Это выглядит уродливо. Есть ли какой-либо шаблон дизайна, который упростил бы это?
* Используемый язык: Ruby. Хотя я считаю, что решение должно быть языковым агностиком
Ответы
Ответ 1
Если существует слишком много условий, не связанных с ремонтопригодностью, самое лучшее, что вы можете сделать, это абстракция.
- Группируйте аналогичные условия по их функциональности и называйте эту функциональность.
- Создайте
Boolean
методы возврата для каждой группы и вызовите их в блоке if
.
Ответ 2
В Agile Programming: дизайн для размещения
Изменить, Дейв Томас рекомендует таблицы решений:
Немногие разработчики знакомы с решением таблицы - один из самых простых и самые мощные методы решения со сложной логикой. Таблица решений уникальным в том, что конечный пользователь может легко указать и поддерживать его. Таблица содержит набор условий, расположенных над набор действий для выполнения (см. таблицу 1).
Они, безусловно, являются агностиками языка, поскольку они использовались с начала 1970-х годов.
Ответ 3
Обычно это switch
(C, Java) или операторы case
(Ruby):
shouldAct = false
case
when <condition A>
shouldAct = true
when <condition B>
shouldAct = true
when <condition C>
shouldAct = true
else
shouldAct = false
end
doSomething() if shouldAct
В Python существует сложное решение, использующее кортеж lambdas:
conditions = (
lambda a : a == 1,
lambda b : b == 2,
lambda c : c == 3,
)
# evaluate each condition separately
a,b,c = 1,2,3
if any(map(lambda x, y : x(y), conditions, [a,b,c])):
soSomething()
Обратите внимание, что каждая лямбда вызывается с помощью только одного параметра.
Ответ 4
Трудно сказать без полного контекста.
Один из вариантов состоит в том, чтобы наследовать от базового класса и иметь условие A(), conditionB() и т.д. - реализации метода base condition(). Это имеет свои преимущества, но может не соответствовать этому примеру.
Другой вариант - передать метод condition() в качестве параметра для метода, который использует это условие. Эта опция делает предположение, что существует умный способ хранения методов condition(), которые будут переданы методу.