设计模式之组合模式

  最近跟同事一起分享了一下电商中订单优惠系统的设计,其中包含了一部分优惠条件的组合的设计,实现单个条件和组合条件可以统一处理,简化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

原文地址:https://www.cnblogs.com/oneheart/p/9142416.html