策略+简单工厂模式优化大量if-else分支

背景

        规则匹配需求:

                规则包括相等、不等、正则匹配、包含、不含、为空、不空、大于、小于、区间等等

                数据类型包括字符串、数值型(整形、长整型、浮点数)、时间型(绝对时间、相对时间)

                获取一条记录,提取其中某个字段,根据字段类型,与给定的值根据规则进行判定,满足返回true

实现

       初版

        使用大量if-else分支根据字段类型规则两个逻辑条件进行判定(最终写了大几百行)

if (type.equal("varchar") || type.equal("text")) {
    if(rule.equal("equal")) {
        // TODO 判定逻辑
    } else if (rule.equal("empty")) {
        // TODO 判定逻辑
    }
    
    ...
} else if (type.equal("integer")) {
    if(rule.equal("equal")) {
        // TODO 判定逻辑
    } else if (rule.equal("empty")) {
        // TODO 判定逻辑
    }
    
    ...
}

...

优点:长驱直入,通俗易懂

缺点:分支判断全在客户端,维护不易,不易扩展,看着恶心            

        二版

        使用策略模式+简单工厂

  • 接口类
public  interface RuleMatching {
    /**
     * 规则匹配
     * @return
     */
    boolean ruleMatching(String indicatorValue, String value1, String value2);
}
  • 具体实现类
public class StringEqual implements RuleMatching {
    @Override
    public boolean ruleMatching(String indicatorValue, String value1, String value2) {
        if (!indicatorValue.equals(value1)) {
            return false;
        }
        return true;
    }
}
public class StringInclude implements RuleMatching {
    @Override
    public boolean ruleMatching(String indicatorValue, String value1, String value2) {
        if (!indicatorValue.contains(value1)) {
            return false;
        }
        return true;
    }
}

每种类型每种规则都会有一个对应的类

  • 上下文类
public class RuleMatchingContext {

    RuleMatching ruleMatching;

    public void init (String operator, String dataType) {

        boolean isString = "varchar".equals(dataType);
        boolean isIntegerNumber = "integer".equals(dataType);
        boolean isBigintNumber = "bigint".equals(dataType);
        boolean isDoubleNumber = "double".equals(dataType);
        boolean isTime = "timestamp".equals(dataType);

        if (isString) {
            switch (operator) {
                case "equal":
                    ruleMatching = new StringEqual();
                    break;
                case "unequal":
                    ruleMatching = new StringUnequal();
                    break;
					
				...
				
                default:
                    break;
            }
        } else if (isIntegerNumber) {
            switch (operator) {
                case "equal":
                    ruleMatching = new IntegerEqual();
                    break;
					
				...
				
                default:
                    break;
            }
        } else if (isBigintNumber) {
            ...
        } else if (isDoubleNumber) {
            ...
        } else if (isTime) {
            ...
        }
    }

    public boolean ruleMatching(String indicatorValue, String value1, String value2) {
        return ruleMatching.ruleMatching(indicatorValue, value1, value2);
    }
}
  • 客户端
RuleMatchingContext ruleMatchingContext = new RuleMatchingContext();

// 根据不同的数据类型和规则由上下文实例化相应的类
ruleMatchingContext.init(conditionRule, indicatorType);

boolean b = ruleMatchingContext.ruleMatching(indicatorValue, value1, value2);

优点:解放了客户端,有新的需求只需要增加相应的类,并在contenxt中添加相应实例化方式。

缺点:类太多了(也不算缺点吧),分支逻辑放在了context中,按设计模式的思想来看,还是没有满足面对修改封闭的原则。

以上便是使用策略模式+简单工厂优化大量if-else分支的具体实现,至于简单工厂的一些弊端,在以后的工厂方法模式和抽象工厂模式中会有更深层的一些探讨,这里暂不啰嗦。

你可能感兴趣的:(设计模式,设计模式,策略模式,简单工厂模式)