组合模式 傷城~ 2021-12-09 00:49 243阅读 0赞 ## 前言 ## **组合模式(Composite)**,将对象组合树形结构以表示‘部分-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。 ## 一、Component 类 ## Component为组合中的对象声明接口,在适当情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component的子部件。 1 public abstract class Component 2 { 3 protected string name; 4 public Component(string name) 5 { 6 this.name = name; 7 } 8 //通常用add方法来提供增加树叶或树枝的功能 9 public abstract void Add(Component c); 10 //通常用remove方法来提供移除树叶或树枝的功能 11 public abstract void Remove(Component c); 12 public abstract void Display(int depth); 13 } ## 二、Leaf在组合中表示叶节点对象,叶节点没有子节点。 ## ** 由于叶子没有再增加分支和树叶,所以add和remove方法实现它没有意义,但这样做可以消除叶节点和枝节点对象在抽象层次的区别,他们具备完全一致的接口。** 1 public class Leaf : Component 2 { 3 public Leaf(string name) : base(name) 4 { 5 } 6 7 public override void Add(Component c) 8 { 9 Console.WriteLine("不需要添加树叶"); 10 } 11 12 public override void Display(int depth) 13 { 14 Console.WriteLine(new string('-', depth) + name); 15 } 16 17 public override void Remove(Component c) 18 { 19 Console.WriteLine("不需要移除树叶"); 20 } 21 } ## 三、Composite类 ## Composite定义有枝节点行为,用来存储子部件,在component接口中实现与子部件有关的操作。 1 public class Composite : Component 2 { 3 private List<Component> children = new List<Component>(); 4 public Composite(string name) : base(name) 5 { 6 } 7 8 public override void Add(Component c) 9 { 10 children.Add(c); 11 } 12 13 public override void Display(int depth) 14 { 15 Console.WriteLine(new string('-', depth) + name); 16 foreach(var c in children) 17 { 18 c.Display(depth + 2); 19 } 20 } 21 22 public override void Remove(Component c) 23 { 24 children.Remove(c); 25 } 26 } ## 四、客户端 ## 1 class Program 2 { 3 static void Main(string[] args) 4 { 5 //生成树根root,根上长出两叶leafA和leafB 6 Composite root = new Composite("root"); 7 root.Add(new Leaf("Leaf A")); 8 root.Add(new Leaf("Leaf B")); 9 10 //根上 长出分支Composite X,分支上也有两叶leafXA和leafXB 11 Composite comp = new Composite("Composite X"); 12 comp.Add(new Leaf("Leaf XA")); 13 comp.Add(new Leaf("Leaf XB")); 14 15 root.Add(comp); 16 17 //Composite X再长出分支Composite XY,分支上也有两只leafXYA和leafXYB 18 Composite comp2 = new Composite("Composite XY"); 19 comp2.Add(new Leaf("Leaf XYA")); 20 comp2.Add(new Leaf("Leaf XYB")); 21 22 comp.Add(comp2); 23 24 //根上又长出两叶LeafC和LeafD 25 root.Add(new Leaf("Leaf C")); 26 //leafD 没长好 被吃了 27 Leaf leaf = new Leaf("Leaf D"); 28 root.Add(leaf); 29 root.Remove(leaf); 30 31 root.Display(1); 32 33 Console.ReadKey(); 34 } 35 } ## 总结 ## 1、**透明模式:**在Component中声明所有用来管理子对象的方法,其中Add,Remove等,这样实现Component接口的所有子类都具备了Add和Remove。这样做的好处就是叶节点和枝节点对外没有区别。他们具有完备统一的接口。但问题也很明显,因为Leaf类本身不具备Add()、Remove()方法的功能,所以实现它没有意义的。 2、**安全模式:** 在Component接口中不去声明Add和Remove方法,那么子类的leaf也就不需要去实现它,而Composite声明所有用来管理子类对象的方法,这样做就不会出现刚才提到的问题,不过由于不透明,所以树叶和树枝类将不具备相同的接口,客户端的调用需要做相应的判断,带来不便。 3、当你发现需求中使体现部分与整体层次的结构时,以及你希望用户可以忽略组合对象 与单个对象的不同,统一地使用组合结构中的所有对象时,就应该考虑用组合模式。 **参考书籍:**大话设计模式
还没有评论,来说两句吧...