zoukankan      html  css  js  c++  java
  • 设计模式之组合模式

      最近跟同事一起分享了一下电商中订单优惠系统的设计,其中包含了一部分优惠条件的组合的设计,实现单个条件和组合条件可以统一处理,简化client的使用。

    需求简单描述如下:(条件1 and/or 条件2)and/or 条件3,改方式满足则执行优惠内容。

    这里我们只讨论如何设计组合条件,能够达到方便扩展,简化使用的目的。这里我使用的是组合模式来处理设计。

    组合模式的UML模型如下(盗用)

    Component:抽象单个或组合条件,提供统一的引用,达到简单使用的目的

    Composite:组合条件,内部包含叶子条件或组合条件集合,条件之间存在与/或的关系

    Leaf:单个条件,每个叶子节点提供真实的条件判断逻辑

    Client端通过Component的Operation调用即可实现组合及叶子节点的Operation的递归调用。

      按照组合模式的UML开始设计组合条件。

    抽象条件类  

    public abstract class ComponentCondition
    {
        public abstract void Add(ComponentCondition condition);
            
        public abstract List<ComponentCondition> GetChildren();
    
        public abstract bool Match();
    }

    叶子条件类

        public class LeafCondition : ComponentCondition
        {
            public override void Add(ComponentCondition condition)
            {
                return;
            }
    
            public bool IsMatch { get; set; }
    
            public override List<ComponentCondition> GetChildren()
            {
                return null;
            }
    
            public override bool Match()
            {
                Console.WriteLine("匹配结果{0}",IsMatch);
                return IsMatch;
            }
        }

    组合条件类

        public class CompositeCondition : ComponentCondition
        {
            private List<ComponentCondition> _conditions;
    
            private RelationOperator _relationOperator;
    
            public CompositeCondition(RelationOperator relationOperator)
            {
                _relationOperator = relationOperator;
            }
    
            public override void Add(ComponentCondition condition)
            {
                if (_conditions == null)
                {
                    _conditions = new List<ComponentCondition>();
                }
                _conditions.Add(condition);
            }
    
            public override List<ComponentCondition> GetChildren()
            {
                if (_conditions == null)
                {
                    _conditions = new List<ComponentCondition>();
                }
                return _conditions;
            }
    
            public override bool Match()
            {
                var children = this.GetChildren();
                return _relationOperator.Match(children);
            }
        }

    组合条件中子条件的关系有And / Or 的关系

        public interface RelationOperator
        {
            bool Match(List<ComponentCondition> conditions);
        }
    
        public class AndOperator : RelationOperator
        {
            public bool Match(List<ComponentCondition> conditions)
            {
                return conditions.All(c => c.Match());
            }
        }
    
        public class OrOperator : RelationOperator
        {
            public bool Match(List<ComponentCondition> conditions)
            {
                return conditions.Any(c => c.Match());
            }
        }

    以上代码设计完成了组合条件的功能,我们下面看一下Client端如何使用

        public class ConditionClient
        {
            public void Excute()
            {
                //组合条件根节点
                ComponentCondition root = new CompositeCondition(new OrOperator());
                //二级叶子节点
                root.Add(new LeafCondition() { IsMatch = false });
                //二级组合条件
                ComponentCondition sencond = new CompositeCondition(new AndOperator());
                sencond.Add(new LeafCondition() { IsMatch = true });
                sencond.Add(new LeafCondition() { IsMatch = false });
                root.Add(sencond);
                //
                Console.WriteLine("result is "+ root.Match());
            }
        }

    Client条件中设计了一个树形的组合条件:条件1 Or (条件2 And 条件3),由于(条件3=false),结果为 false

  • 相关阅读:
    Git 使用juju
    svn Q&A
    ubuntu 常用命令
    java中set的交集、差集、并集的简单实现
    java 读写JSON(一)
    java类型转化之SimpleDateFormat-时间转化
    maven 基本常识以及命令
    maven遇到的问题
    java编程思想,对象导论
    条目5:避免创建不必要的对象
  • 原文地址:https://www.cnblogs.com/oneheart/p/9142416.html
Copyright © 2011-2022 走看看