Имеет ли смысл в этом случае заменять сложные условные выражения на шаблон Стратегии? - PullRequest
0 голосов
/ 17 февраля 2019

У меня есть значение, которое нужно возвращать из метода, только если выполняются определенные условия, в противном случае я должен вернуть ноль.
Этот метод получает 2 логических параметра, в зависимости от которых вызываются дополнительные методы для проверки некоторых других условий.

Call method1, then method2 -> if (param1 && param2) == true;
Don't call any method-> if (!param1 && !param2) == true;
Call only method1 -> if only param1 == true;
Call only method2 -> if only param2 == true; //Method2 is an expensive operation.

Итак, чтобы удовлетворить это требование, я написал код, который выглядит следующим образом -

value = doSomeProcessingToGetValue(); //Not an expensive operation
if(param1 && param2) //both are true {
    if(method1() != null) { // if method1 return true then move ahead
        if(method2() != null) { //if method2 return true then move ahead (Expensive operation)
            return value; //Means all the conditions are satisfied now
        }
    }
}
else if(!param1 && !param2) //both are false {
    return value; //No need to check for any condition
}
else if(param1) //Means param1 is true {
    if(method1()!=null) {// if method1 return true then move ahead
        return value; //Means all the conditions are satisfied now
    }
}
else { //Means param2 is true
    if(method2()!=null) {// if method2 return true then move ahead(Expensive operation)
        return value; //Means all the conditions are satisfied now
    }
}
return null;

У меня есть 2 проблемы с вышеупомянутым подходом -

Масштабируемость - Это решение не масштабируемо, потому что в будущем, возможно, потребуется проверить еще несколько параметров с соответствующими методами для их вызова.Итак, нет.проверки if else будут увеличиваться экспоненциально с добавлением каждого параметра.
Не элегантно - Поскольку слишком много условных проверок, оно выглядит не очень элегантно.Чтобы сделать его более элегантным, я думаю о применении паттерна стратегии .
подхода паттерна стратегии Говоря о высоком уровне, я создам конкретные классы для каждого из них, если условие указано выше.Итак, для вышеприведенного кода будет четыре конкретных класса.Я переберу все конкретные классы и проверим, удовлетворяет ли какой-либо из них условиям и вернет ли это значение соответствующим образом.
Мой вопрос - имеет ли смысл использовать шаблон стратегии для удовлетворения этого требования, поскольку это решение также плохо работает вусловия масштабируемости.
Или есть ли лучший подход, который будет хорош с точки зрения масштабируемости.

1 Ответ

0 голосов
/ 17 февраля 2019

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

Но вы написали: «Я переберу все конкретные классы и проверим, удовлетворяет ли какой-либо из них условиям».Вам не нужно перебирать реализации.Вы можете создать стратегическую реализацию во время выполнения, используя, например, factory :

public Strategy getStrategy(boolean param1, boolean param2) {

    if (param1) {
        if (param2) {
            return value -> method1() != null && method2() != null ? value : null;
        } else {
            return value -> method1() != null ? value : null;
        }
    } else {
        if (param2) {
            return value -> method2() != null ? value : null;
        } else {
            return value -> value;
        }
    }
}

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

interface Strategy {
    Object getValue(Object value);
}

Стратегия может быть введена в ваш основной класс с помощью параметра construtor или метода установки.Как видите, фабрика становится другим местом для ваших условий.Таким образом, по крайней мере некоторые условия входят в конкретные реализации.

Кроме того, замена условия на полиморфизм шаблон рефакторинга и обсуждение стека в потоке может быть полезным.

И еще одна вещь.Похоже, что состояние вашего экземпляра класса зависит от param1 и param2.Таким образом, другим конструктивным решением может быть конечный автомат

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...