@ddd329

Как избавиться от многочисленных if/else?

Доброго времени суток!

Имеется примерно такой псевдокод для неких расчетов:
IF Условие 1 THEN
    Делаем расчеты первым методом
ELSE IF Условие 2 THEN
    Делаем расчеты вторым методом
ELSE IF Условие 3 THEN
    Делаем расчеты третьим методом
ELSE
    Здесь обращаемся к базе данных и находим последнее валидное значение
END


Суть в том, что необходимо сделать расчеты. Выберем для этого первый метод, если не получилось первым, то нужно попробовать вторым, иначе попробовать третьим, но в случае, если все методы не принесли успешных результатов, то необходимо обратиться к Базе Данных и там найти последнее успешное значение.

Таких вот if/else по коду может около 20, причем тут идет смешение разной логики: бизнес-логики и логики обращения к БД.

Знаете ли вы как можно "красиво" организовать подобный код? Может какие-нибудь паттерны проектирования можно применить?
  • Вопрос задан
  • 753 просмотра
Решения вопроса 1
Adamos
@Adamos
class CalculationData;

abstract class Calculation 
{
  public function calculate(CalculationData data);
}

class CalculationQueue 
{
  public function addCalculation(Calculation calculationVariant, int priority);

  public function calculate(CalculationData data) {     
     for (c in calculations) {
       if(res = c.calculate(data)) return res;
     }
  }
}
Ответ написан
Пригласить эксперта
Ответы на вопрос 5
@antonwx
Очевидный switch. Есть в большинстве языков.
Ответ написан
sergey-gornostaev
@sergey-gornostaev
Седой и строгий
Обычно пелёнка условных выражений (особенно многоуровневая) является сигналом о возможности использовать паттерн состояние. Так же полезно выполнить декомпозицию кода принимающего решения и кода выполняющего вычисления, то есть возвращать не результат вычислений, а выполняющее их поведение. Совсем хорошо, если завернуть его в maybe-тип, чтобы вызывающий код мог делегировать получение значения по умолчанию другому коду.
Ответ написан
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Выберем для этого первый метод, если не получилось первым, то нужно попробовать вторым, иначе попробовать третьим, но в случае, если все методы не принесли успешных результатов, то необходимо обратиться к Базе Данных и там найти последнее успешное значение.
Ваш код не соответствует этому описанию. В приведённой цепочке if-else выполнение какого-либо метода зависит не от результата предыдущего метода, а от набора неких внешних условий. Для цепочки можно использовать
result = tryMethod1() || tryMethod2() || ... || getFromDB();
Ответ написан
@SteelJames
всё зависит от того, как устроены условия и выполняемые действия.
Без этой конкретики ответа быть не может, кроме очевидного switch
Ответ написан
solotony
@solotony
покоряю пик Балмера
тут смотря что за условия

если условие сравнение с константой, и таких условий много я бы использовал словарь (ассоциативный массив) в значениях которого были бы указатели на функцию

если же условия сами по себе являются какими-то вычислениям, то тут конечно без перебора не обойтись.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы