设计模式之组合模式
最近跟同事一起分享了一下电商中订单优惠系统的设计,其中包含了一部分优惠条件的组合的设计,实现单个条件和组合条件可以统一处理,简化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
学习什么时候都不晚,从现在起我们一起