什麼是組合模式? 組合模式(Composite):將對象組合成樹形結構以表示“部分-整體”的層次結構。 組合模式使得用戶對單個對象和組合對象的使用具有一致性。 何時使用組合模式? 當需求中是體現部分與整體層次的結構時,以及你希望用戶可以忽略組合對象與單個對象的不同,同意地使用組合結構中的所有對象時, ...
什麼是組合模式?
組合模式(Composite):將對象組合成樹形結構以表示“部分-整體”的層次結構。
組合模式使得用戶對單個對象和組合對象的使用具有一致性。
何時使用組合模式?
當需求中是體現部分與整體層次的結構時,以及你希望用戶可以忽略組合對象與單個對象的不同,同意地使用組合結構中的所有對象時,就應該考慮用組合模式。
組合模式的組成
Component:組合中的對象聲明介面,在適當情況下,實現所有類共有介面的預設行為。
聲明一個介面用於訪問和管理Component的子部件。
Leaf:在組合中表示葉節點對象,葉節點沒有子節點。
Composite:定義有枝節點行為,用來存儲子部件,在Component介面中實現與子部件有關的操作,比如增加Add和刪除Remove
組合模式具體實現
組合模式的結構
組合模式的實現:
Component類:
1 abstract class Component 2 { 3 protected string name; 4 public Component(string name) 5 { 6 this.name = name; 7 } 8 public abstract void Add(Component c); 9 public abstract void Remove(Component c); 10 public abstract void Diaplay(int depth); 11 }
Leaf類:
1 class Leaf : Component 2 { 3 public Leaf(string name) : base(name) 4 { } 5 6 public override void Add(Component c) 7 { 8 Console.WriteLine("Cannot add a leaf"); 9 } 10 11 public override void Diaplay(int depth) 12 { 13 Console.WriteLine(new String('-', depth) + name); 14 } 15 16 public override void Remove(Component c) 17 { 18 Console.WriteLine("Cannot remove from a leaf"); 19 } 20 }
Composite類:
1 class Composite : Component 2 { 3 private List<Component> children = new List<Component>(); 4 public Composite(string name) : base(name) 5 { } 6 7 public override void Add(Component c) 8 { 9 children.Add(c); 10 } 11 12 public override void Diaplay(int depth) 13 { 14 //將 System.String 類的新實例初始化為由重覆指定次數的指定 Unicode 字元指示的值 15 Console.WriteLine(new String('-', depth) + name); 16 foreach(Component component in children) 17 { 18 component.Diaplay(depth + 2); 19 } 20 } 21 22 public override void Remove(Component c) 23 { 24 children.Remove(c); 25 } 26 }
主函數調用:
1 static void Main(string[] args) 2 { 3 Composite root = new Composite("root"); 4 root.Add(new Leaf("Leaf A")); 5 root.Add(new Leaf("Leaf B")); 6 7 Composite comp = new Composite("Composite X"); 8 comp.Add(new Leaf("Leaf XA")); 9 comp.Add(new Leaf("Leaf XB")); 10 11 root.Add(comp); 12 13 Composite comp2 = new Composite("Composite XY"); 14 comp2.Add(new Leaf("Leaf XYA")); 15 comp2.Add(new Leaf("Leaf XYB")); 16 17 comp.Add(comp2); 18 19 root.Add(new Leaf("Leaf C")); 20 21 Leaf leaf = new Leaf("Leaf D"); 22 root.Add(leaf); 23 root.Remove(leaf); 24 25 root.Diaplay(1); 26 27 Console.Read(); 28 }
實現效果:
實例解析
為了深化理解,我們準備一個具體的實例來分析。
分析:
具體實現:
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 ConcreteCompany root = new ConcreteCompany("北京公司總部"); 6 root.Add(new HRDepartment("北京公司總部人力資源部")); 7 root.Add(new FinanceDepartment("北京公司總部財務部")); 8 9 ConcreteCompany com = new ConcreteCompany("上海分公司"); 10 com.Add(new HRDepartment("上海分公司人力資源部")); 11 com.Add(new FinanceDepartment("上海分公司財務部")); 12 13 root.Add(com); 14 15 ConcreteCompany com2 = new ConcreteCompany("南京辦事處"); 16 com2.Add(new HRDepartment("南京辦事處人力資源部")); 17 com2.Add(new FinanceDepartment("南京辦事處財務部")); 18 19 com.Add(com2); 20 21 ConcreteCompany com3 = new ConcreteCompany("杭州辦事處"); 22 com3.Add(new HRDepartment("杭州辦事處人力資源部")); 23 com3.Add(new FinanceDepartment("杭州辦事處財務部")); 24 com.Add(com3); 25 26 Console.WriteLine("\n結構圖:"); 27 root.Diaplay(1); 28 29 Console.WriteLine("\n職責:"); 30 root.LineOfDuty(); 31 Console.Read(); 32 } 33 } 34 abstract class Company 35 { 36 protected string name; 37 public Company(string name) 38 { 39 this.name = name; 40 } 41 public abstract void Add(Company c); 42 public abstract void Remove(Company c); 43 public abstract void Diaplay(int depth); 44 public abstract void LineOfDuty(); 45 } 46 class ConcreteCompany : Company 47 { 48 private List<Company> children = new List<Company>(); 49 public ConcreteCompany(string name) : base(name) 50 { } 51 52 public override void Add(Company c) 53 { 54 children.Add(c); 55 } 56 57 public override void Diaplay(int depth) 58 { 59 Console.WriteLine(new String('-', depth) + name); 60 foreach(Company company in children) 61 { 62 company.Diaplay(depth + 2); 63 } 64 } 65 66 public override void LineOfDuty() 67 { 68 foreach(Company component in children) 69 { 70 component.LineOfDuty(); 71 } 72 } 73 74 public override void Remove(Company c) 75 { 76 children.Remove(c); 77 } 78 } 79 class HRDepartment : Company 80 { 81 public HRDepartment(string name) : base(name) 82 { 83 } 84 85 public override void Add(Company c) 86 { } 87 88 public override void Diaplay(int depth) 89 { 90 Console.WriteLine(new String('-', depth) + name); 91 } 92 93 public override void LineOfDuty() 94 { Console.WriteLine("{0} 員工招聘培訓管理", name); } 95 96 public override void Remove(Company c) 97 { } 98 } 99 class FinanceDepartment : Company 100 { 101 public FinanceDepartment(string name) : base(name) 102 { } 103 104 public override void Add(Company c) 105 { } 106 107 public override void Diaplay(int depth) 108 { 109 Console.WriteLine(new String('-', depth) + name); 110 } 111 112 public override void LineOfDuty() 113 { 114 Console.WriteLine("{0} 公司財務收支管理", name); 115 } 116 117 public override void Remove(Company c) 118 { } 119 }
備註:文中所有代碼及知識點均來自於《大話設計模式》,本人屬於邊學邊看邊敲代碼邊總結的階段。