• 设计模式-组合模式


    应用场景

    实现规则匹配的逻辑 比如>= <=,同时支持 and or 多个条件组合 新增一个条件就增加一个实现类

    说明

    对于这种需要实现规则匹配的逻辑,可以考虑使用策略模式。策略模式可以将不同的算法封装成不同的策略类,让它们可以相互替换,从而实现不同的行为。在这个问题中,可以将不同的匹配规则封装成不同的策略类,让它们可以相互替换,从而实现不同的匹配行为。

    1、具体实现时,可以定义一个接口,例如 MatchStrategy,其中包含一个 match 方法,用于判断给定的值是否满足当前规则。然后,针对不同的规则,可以实现不同的策略类,例如 GreaterThanStrategy、LessThanStrategy、EqualStrategy 等,它们分别实现 MatchStrategy 接口,并实现自己的 match 方法。
    2、对于多个条件组合的情况,可以使用组合模式来实现。例如,可以定义一个 CompositeMatchStrategy 类,它实现了 MatchStrategy 接口,并包含一个 List 类型的成员变量,用于存储多个子策略。然后,可以定义一个 AndMatchStrategy 类和一个 OrMatchStrategy 类,它们都是 CompositeMatchStrategy 的子类,分别实现了 “and” 和 “or” 运算符的匹配逻辑。

    这样,当需要新增一个条件时,只需要新增一个实现了 MatchStrategy 接口的策略类,并将它加入到 CompositeMatchStrategy 中即可。整个匹配逻辑的实现就变得非常灵活和可扩展了。

    实现

    假设我们需要实现一个匹配规则的功能,支持以下几种规则:

    • 大于等于某个值
    • 小于等于某个值
    • 等于某个值
    • 大于某个值
    • 小于某个值
      同时,还需要支持 “and” 和 “or” 运算符,让用户可以将多个规则组合起来使用。

    1、首先顶定义一个MatchStrategy 接口,用于表示匹配规则

    /**
     * @author lsh
     * @date 2023/6/9
     */
    public interface MatchStrategy {
        boolean match(String value);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2、然后,我们针对不同的规则,实现不同的策略类。例如,对于大于某个值的规则,我们可以实现一个 MatchStrategyImpl1 类:

    /**
     * 匹配规则 大于0
     */
    public class MatchStrategyImpl1 implements MatchStrategy{
        @Override
        public boolean match(Integer value) {
            return value>0;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    类似地,我们还可以实现其他的策略类,这些类都实现了 MatchStrategy 接口,并实现了自己的 match 方法。
    3、接下来,我们实现组合模式。我们定义一个 CompositeMatchStrategy 类,用于表示多个匹配规则的组合

    /**
     * 组合匹配规则
     */
    public abstract class CompositeMatchStrategy implements MatchStrategy {
        protected List<MatchStrategy> strategies = new ArrayList<>();
    
        public void addStrategy(MatchStrategy strategy) {
            strategies.add(strategy);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    这个类是一个抽象类,包含一个 List 类型的成员变量 strategies,用于存储多个子策略。它还包含一个 addStrategy 方法,用于向 strategies 中添加子策略。
    4、针对 “and” 和 “or” 运算符,分别实现 AndMatchStrategy 和 OrMatchStrategy 类,它们都是 CompositeMatchStrategy 的子类

    /**
     * 或 组合规则
     */
    public class OrMatchStrategy extends CompositeMatchStrategy {
        @Override
        public boolean match(Integer value) {
            for (MatchStrategy strategy : strategies) {
                if (strategy.match(value)) {
                    return true;
                }
            }
            return false;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    /**
     * 且 组合规则
     */
    public class AndMatchStrategy extends CompositeMatchStrategy {
        @Override
        public boolean match(Integer value) {
            for (MatchStrategy strategy : strategies) {
                if (!strategy.match(value)) {
                    return false;
                }
            }
            return true;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    5、测试
    我们期望匹配大于零并且小于3

     CompositeMatchStrategy  strategy = new AndMatchStrategy();
            strategy.addStrategy(new MatchStrategyImpl1());
            strategy.addStrategy(new MatchStrategyImpl2(3));
            if(strategy.match(1)){
            	//匹配成功
                log.info("1--------------------------------匹配成功");
            }else{
                log.info("1--------------------------------匹配失败");
            }
            if(strategy.match(4)){
            	//匹配成功
                log.info("4--------------------------------匹配成功");
            }else{
                log.info("4--------------------------------匹配失败");
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    在这里插入图片描述
    这样,我们就可以灵活地组合多个规则,并实现复杂的匹配逻辑了。

  • 相关阅读:
    GBase 8d的特性-可用性
    nginx之正向代理、反向代理和负载均衡(重点)
    你需要的免费热门API接口这里都有~
    HashMap为什么会发生死循环?
    《微信小程序-进阶篇》Lin-ui组件库源码分析-动画组件Transition(一)
    C++基础从0到1入门编程(二)
    Python的优点和缺点
    题目 1060: 二级C语言-同因查找
    路由器热备份
    JavaScript 中的 Range 和 Selection 对象
  • 原文地址:https://blog.csdn.net/weixin_44792849/article/details/131126170