组合模式容许你将对象组合成树形结构来表现”部分-总体“的层次结构,使得客户以一致的方式处理单个对象以及对象的组合。下面咱们用绘制的例子来详细介绍组合模式,图形能够由一些基本图形元素组成(如直线,圆等),也能够由一些复杂图形组成(由基本图形元素组合而成),为了使客户对基本图形和复杂图形的调用保持一致,咱们使用组合模式来达到整个目的。设计模式
组合模式实现的最关键的地方是——简单对象和复合对象必须实现相同的接口。这就是组合模式可以将组合对象和简单对象进行一致处理的缘由。安全
Component为组合中的对象声明接口,在适当状况下,实现全部类共有接口的默认行为。声明一个接口用于访问和管理Component的子部件。ide
abstract class Component { protected string name; public Component(string name) { this.name = name; } public abstract void Add(Component c); public abstract void Remove(Component c); public abstract void Display(int depth); }
Leaf在组合中标识叶节点对象,叶节点没有子节点。post
class Leaf : Component { public Leaf(string name) : base(name) { } public override void Add(Component c) { Console.WriteLine("Cannot add to a leaf"); } public override void Remove(Component c) { Console.WriteLine("Cannot remove from a leaf"); } public override void Display(int depth) { Console.WriteLine(new String('-', depth) + name); } }
Composite定义有枝节点行为,用来存储子部件,在Composite接口中实现与子部件有关的操做,好比增长ADD和删除Remove。this
class Composite : Component { private List<Component> children = new List<Component>(); public Composite(string name) : base(name) { } public override void Add(Component c) { children.Add(c); } public override void Remove(Component c) { children.Remove(c); } public override void Display(int depth) { Console.WriteLine(new String('-', depth) + name); foreach (Component component in children) { component.Display(depth + 2); } } }
客户端代码:spa
class Program { static void Main(string[] args) { Composite root = new Composite("root"); root.Add(new Leaf("Leaf A")); root.Add(new Leaf("Leaf B")); Composite comp = new Composite("Composite X"); comp.Add(new Leaf("Leaf XA")); comp.Add(new Leaf("Leaf XB")); root.Add(comp); Composite comp2 = new Composite("Composite XY"); comp2.Add(new Leaf("Leaf XYA")); comp2.Add(new Leaf("Leaf XYB")); comp.Add(comp2); root.Add(new Leaf("Leaf C")); Leaf leaf = new Leaf("Leaf D"); root.Add(leaf); root.Remove(leaf); root.Display(1); Console.Read(); } }
结果显示:设计
3、透明方式与安全方式code
透明方式:在Ccomponent中声明全部用来管理子对象的方法,其中包括ADD,Remove等。这样实现Component接口的全部子类都具有了Add,Remove。这样作的好处就是叶节点和枝节点对于外界没有区别,他们具有彻底一致的行为接口。但为题也很明显,由于Leaf类自己不具有Add(),Remove()方法功能,因此实现他是没有意义。component
安全方式:在Component接口中不去声音Add,Remove 方法,那么子类的Left就不须要去实现它,而是在Compostie生硬全部用来管理子类对象的方法,这样作就不会出现上面的问题,不过因为不够透明,全部树叶和树枝类将不具备相同的接口,客户端调用须要作相应的判断,带来的不方便。对象
4、组合模式的优缺点
优势:
缺点:使得设计更加复杂。客户端须要花更多时间理清类之间的层次关系。(这个是几乎全部设计模式所面临的问题)。
在如下状况下应该考虑使用组合模式: