組合模式容許你將對象組合成樹形結構來表現」部分-總體「的層次結構,使得客戶以一致的方式處理單個對象以及對象的組合。下面咱們用繪製的例子來詳細介紹組合模式,圖形能夠由一些基本圖形元素組成(如直線,圓等),也能夠由一些複雜圖形組成(由基本圖形元素組合而成),爲了使客戶對基本圖形和複雜圖形的調用保持一致,咱們使用組合模式來達到整個目的。設計模式
組合模式實現的最關鍵的地方是——簡單對象和複合對象必須實現相同的接口。這就是組合模式可以將組合對象和簡單對象進行一致處理的緣由。安全
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、組合模式的優缺點
優勢:
缺點:使得設計更加複雜。客戶端須要花更多時間理清類之間的層次關係。(這個是幾乎全部設計模式所面臨的問題)。
在如下狀況下應該考慮使用組合模式: