Как динамически добавлять условия в соответствии с различными требованиями? - PullRequest
2 голосов
/ 11 ноября 2019

Я пишу код на Java, чтобы включить различные компоненты. Каждый компонент должен удовлетворять определенному набору условий для включения. Каждое условие - это в основном метод, который выполняет некоторую логику и возвращает логическое значение. В настоящее время я написал код, в котором есть разные методы для выполнения логики включения для каждого компонента, и что соответствующий метод выполняет условные операции для возврата логического значения. Моя текущая реализация включения разных компонентов выглядит примерно так:

private boolean shouldEnableComponent1() {
    String param1 = getParam1();
    String param2 = getParam2();
    String param3 = getParam3();
    if(checkCondition1(param1) && checkCondition2(param2) && checkCondition3(param3) {
       return true;
    } else {
        return false;
    }
}

private boolean shouldEnableComponent2() {
    String param1 = getParam1();
    String param2 = getParam2();
    String param4 = getParam4();
    if(checkCondition1(param1) && checkCondition2(param2) && checkCondition4(param4) {
       return true;
    } else {
        return false;
    }
}

Обратите внимание, что разные методы shouldEnableComponentN () могут вызывать одни и те же условные методы, как и в предыдущем случае, оба mustEnableComponent1 () и shouldEnableComponent2 () вызывают checkCondition1() и checkCondition2 (). Разница между их разрешающим условием заключается в 3-й условной проверке, т.е. checkCondition3 () в случае component1 и checkCondition4 () в случае component2.
Это наиболее очевидная реализация, которую я мог бы придумать, но у нее мало проблем -
Duplicity - Так как существует условное совпадение между условными проверками различных компонентов, эта часть кодадублируется.
Масштабируемость - Сегодня будет 3 компонента, завтра будет 10 компонентов. Итак, мне нужно будет реализовать 10 различных методов для каждого компонента. Это определенно плохо.

Я думаю о шаблоне стратегии для этого варианта использования, но я не уверен, как реализовать его здесь. Является ли шаблон стратегии правильным выбором? Если да, пожалуйста, дайте общее представление о том, как это будет реализовано, например, куда я помещу общие переменные, которые необходимо использовать в разных классах, где будет размещена общая логическая часть всех конкретных классов и т. Д. Или есть ли другой дизайн? шаблон, который будет лучше, чем шаблон стратегии для этого варианта использования? Заранее спасибо

1 Ответ

1 голос
/ 11 ноября 2019

Одна идея, которая приходит мне в голову, заключается в предоставлении логического имени параметрам (при условии, что все они являются строками, как вы указали в вопросе):

Учитывая, что набор параметров известен в компиляциивремя, когда вы можете создать «реестр» параметров:

enum ParamName {
   PARAM1, PARAM2, PARAM3... PARAM_N;
}

class ConditionChecker {
   private Map<ParamName, Predicate<String>> registry;

   public ConditionChecker() {

        map.put(ParamName.PARAM1, this::conditionCheck1);
        map.put(ParamName.PARAM2, this::conditionCheck2);
        // populate the map with all conditions for all possible parameters 
   }

   // knows how to check param1
   private Boolean conditionCheck1(String param1) {
       ...
   }

   // knows how to check param2
   private Boolean conditionCheck2(String param2) {
      ...
   }
   ...


}

Теперь укажите «общий» метод проверки условий:

 class ConditionChecker { // the same class as above, continuing...


      public boolean checkAll(Map<ParamName, String value> allParams) {
         // for each element in the map call
         for(Entry<ParamName, String> entry : allParams.entrySet()) {
            if(! registry.get(entry.getKey()).accept(entry.getValue())) {
                 return false; // at least one check failed
             }                
         } 
         // all validations passed
         return true;
      } 
 }

Теперь в shouldEnableComponent1, который обладает информацией, котораяпараметры должны быть точно проверены "вы можете сделать что-то вроде этого:

boolean shouldEnableComponent1() {
     Map<ParamName, String> paramMap = extractMapForParams(PARAM1, PARAM2, PARAM3);
     return conditionChecker.checkAll(paramMap);  
}
...