组合模式(Composite):
定义:
组合模式又叫部分整体模式,它是一种将对象组合成树状的层次结构模式,用来表示"部分-整体"的关系,使用户对单个对象和组合对象具有一致的访问性。
组合模式的角色:
1)抽象构建(Component):它的主要作用是为树叶构件和树枝构件声明公共接口,并实现它们的默认行为。在透明式的组合模式中抽象构件还声明访问和管理子类的接口;在安全式的组合模式中不声明访问和管理子类的接口,管理工作由树枝构件完成。
2)树叶构件(Leaf):是组合中的叶节点对象,它没有子节点,用于实现抽象构件角色中 声明的公共接口。
3)树枝构件(Composite):是组合中的分支节点对象,它有子节点。它实现了抽象构件角色中声明的接口,它的主要作用是存储和管理子部件,通常包含 Add()、Remove()、GetChild() 等方法。
1 internal class Program 2 { 3 private static void Main(string[] args) 4 { 5 // Create a tree structure 6 Composite root = new Composite("root"); 7 root.Add(new Leaf("Leaf A")); 8 root.Add(new Leaf("Leaf B")); 9 10 Composite comp = new Composite("Composite X"); 11 comp.Add(new Leaf("Leaf XA")); 12 comp.Add(new Leaf("Leaf XB")); 13 14 root.Add(comp); 15 root.Add(new Leaf("Leaf C")); 16 17 // Add and remove a leaf 18 Leaf leaf = new Leaf("Leaf D"); 19 root.Add(leaf); 20 root.Remove(leaf); 21 22 // Recursively display tree 23 root.Display(1); 24 } 25 } 26 27 public abstract class Component 28 { 29 protected string _name; 30 31 public Component(string name) 32 { 33 this._name = name; 34 } 35 36 public abstract void Add(Component c); 37 38 public abstract void Remove(Component c); 39 40 public abstract void Display(int depth); 41 } 42 43 public class Leaf : Component 44 { 45 public Leaf(string name) 46 : base(name) 47 { 48 } 49 50 public override void Add(Component c) 51 { 52 Console.WriteLine("Cannot add to a leaf"); 53 } 54 55 public override void Remove(Component c) 56 { 57 Console.WriteLine("Cannot remove from a leaf"); 58 } 59 60 public override void Display(int depth) 61 { 62 Console.WriteLine(new String(\'-\', depth) + _name); 63 } 64 } 65 66 public class Composite : Component 67 { 68 private List<Component> _children = new List<Component>(); 69 70 public Composite(string name) 71 : base(name) 72 { 73 } 74 75 public override void Add(Component component) 76 { 77 _children.Add(component); 78 } 79 80 public override void Remove(Component component) 81 { 82 _children.Remove(component); 83 } 84 85 public override void Display(int depth) 86 { 87 Console.WriteLine(new String(\'-\', depth) + _name); 88 89 foreach (Component component in _children) 90 { 91 component.Display(depth + 2); 92 } 93 } 94 }
极简版如下,将显示部分可以拿到客户端进行:
1 internal class Program 2 { 3 private static void Main(string[] args) 4 { 5 // Create a tree structure 6 Component root = new Component("root"); 7 root.Add(new Component("Leaf A")); 8 root.Add(new Component("Leaf B")); 9 10 Component comp = new Component("Composite X"); 11 comp.Add(new Component("Leaf XA")); 12 comp.Add(new Component("Leaf XB")); 13 14 root.Add(comp); 15 root.Add(new Component("Leaf C")); 16 17 // Add and remove a leaf 18 Component leaf = new Component("Leaf D"); 19 root.Add(leaf); 20 root.Remove(leaf); 21 22 // 由客户端显示,Component只进行组合 23 } 24 } 25 26 public class Component 27 { 28 protected string _name; 29 private List<Component> _children = new List<Component>(); 30 31 public Component(string name) 32 { 33 this._name = name; 34 } 35 36 public void Add(Component c) 37 { 38 _children.Add(c); 39 } 40 41 public void Remove(Component c) 42 { 43 _children.Remove(c); 44 } 45 46 public List<Component> GetChild() 47 { 48 return _children; 49 } 50 }
是不是恍然大悟,就是我们在做权限管理的时候用到的一对多的关系。
组合模式的优缺点:
优点:
1)组合模式使得客户端代码可以一致地处理单个对象和组合对象,无须关心自己处理的单个对象还是组合对象,这简化了客户端代码;
2)更容易在组合体内加入新的对象,客户端不会因为加入新的对象而更改源代码,满足OCP原则。
缺点:
1)设计较复杂,客户端需要花更多的时间理清类之间的层次关系;
2)不容易限制容器中的构件;
3)不容易用继承的方法来增加构件的新功能。