如何根据不同的需求动态添加条件?

时间:2019-11-11 07:22:48

标签: java design-patterns strategy-pattern

我正在用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()方法可能必须调用相同的条件方法,例如在上述情况下,shouldEnableComponent1()和shouldEnableComponent2()都在调用checkCondition1()和checkCondition2()方法。它们的启用条件之间的区别是第三个条件检查,即在component1情况下为checkCondition3()和在component2情况下为checkCondition4()。
这是我能想到的最明显的实现,但是它几乎没有问题-
重复性-由于不同组件的条件检查之间存在重叠,因此该部分代码是重复的。
可扩展性-今天有3个组成部分,明天将有10个组成部分。因此,我将需要为每个组件实现10种不同的方法。绝对不好。

我正在考虑此用例的策略模式,但不确定如何在此处实现它。策略模式是正确的选择吗?如果是的话,请给出将如何实现的高级概念,即我将把需要在各个类之间使用的公共变量放在哪里,所有具体类的公共逻辑部分将放在哪里等。或者是否有其他设计该用例的哪种模式比策略模式更好? 预先感谢

1 个答案:

答案 0 :(得分:1)

我想到的一个想法是为参数提供一些逻辑名称(假设它们都是字符串,如您在问题中所述):

鉴于在编译时已知参数集,您可以创建参数“注册表”:

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);  
}