設計模式-結構型-組合模式
阿新 • • 發佈:2019-09-29
組合模式(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)不容易用繼承的方法來增加構件的新功能。
參考:https://www.cnblogs.com/libingql/p/3496345.