C# 設計形式系列教程-組合形式。本站提示廣大學習愛好者:(C# 設計形式系列教程-組合形式)文章只能為提供參考,不一定能成為您想要的結果。以下是C# 設計形式系列教程-組合形式正文
1. 概述
將對象組分解樹形構造以表現“部門-全體”的條理構造。組合形式使得用戶對單個對象和組合對象的應用具有分歧性。
2. 處理的成績
當願望疏忽單個對象和組合對象的差別,同一應用組合構造中的一切對象(將這類“同一”性封裝起來)。
3. 組合形式中的腳色
3.1 組合部件(Component):它是一個籠統腳色,為要組合的對象供給同一的接口。
3.2 葉子(Leaf):在組合中表現子節點對象,葉子節點不克不及有子節點。
3.3 分解部件(Composite):界說有枝節點的行動,用來存儲部件,完成在Component接口中的有關操作,如增長(Add)和刪除(Remove)。
4. 形式解讀
4.1 組合形式的類圖
4.2 組合形式的完成代碼
/// <summary> /// 一個籠統構件,聲明一個接口用於拜訪和治理Component的子部件 /// </summary> public abstract class Component { protected string name; public Component(string name) { this.name = name; } /// <summary> /// 增長一個節點 /// </summary> /// <param name="component"></param> public abstract void Add(Component component); /// <summary> /// 移除一個節點 /// </summary> /// <param name="component"></param> public abstract void Remove(Component component); /// <summary> /// 顯示層級構造 /// </summary> public abstract void Display(int level); } /// <summary> /// 葉子節點 /// </summary> public class Leaf : Component { public Leaf(string name) : base(name) { } /// <summary> /// 因為葉子節點沒有子節點,所以Add和Remove辦法對它來講沒成心義,但它繼續自Component,如許做可以清除葉節點和枝節點對象在籠統條理的差別,它們具有完整分歧的接口。 /// </summary> /// <param name="component"></param> public override void Add(Component component) { Console.WriteLine("Can not add a component to a leaf."); } /// <summary> /// 完成它沒成心義,只是供給了一個分歧的挪用接口 /// </summary> /// <param name="component"></param> public override void Remove(Component component) { Console.WriteLine("Can not remove a component to a leaf."); } public override void Display(int level) { Console.WriteLine(new string('-',level) + name); } } /// <summary> /// 界說有枝節點的行動,用來存儲部件,完成在Component接口中對子部件有關的操作 /// </summary> public class Composite : Component { public Composite(string name) : base(name) { } /// <summary> /// 一個子對象聚集,用來存儲其部屬的枝節點和葉節點 /// </summary> private List<Component> children = new List<Component>(); /// <summary> /// 增長子節點 /// </summary> /// <param name="component"></param> public override void Add(Component component) { children.Add(component); } /// <summary> /// 移除子節點 /// </summary> /// <param name="component"></param> public override void Remove(Component component) { children.Remove(component); } public override void Display(int level) { Console.WriteLine(new string('-', level) + name); // 遍歷其子節點並顯示 foreach (Component component in children) { component.Display(level+2); } } }
4.3 客戶端代碼
class Program { static void Main(string[] args) { // 生成樹根,並為其增長兩個葉子節點 Component root = new Composite("Root"); root.Add(new Leaf("Leaf A in Root")); root.Add(new Leaf("Leaf B in Root")); // 為根增長兩個枝節點 Component branchX = new Composite("Branch X in Root"); Component branchY = new Composite("Branch Y in Root"); root.Add(branchX); root.Add(branchY); // 為BranchX增長頁節點 branchX.Add(new Leaf("Leaf A in Branch X")); // 為BranchX增長枝節點 Component branchZ = new Composite("Branch Z in Branch X"); branchX.Add(branchZ); // 為BranchY增長葉節點 branchY.Add(new Leaf("Leaf in Branch Y")); // 為BranchZ增長葉節點 branchZ.Add(new Leaf("Leaf in Branch Z")); // 顯示樹 root.Display(1); Console.Read(); } }
運轉成果
5. 通明方法與平安方法
5.1 通明方法:在Component中聲明一切來治理子對象的辦法,個中包含Add,Remove等。如許完成Component接口的一切子類都具有了Add和Remove辦法。如許做的利益是葉節點和枝節點關於外界沒有差別,它們具有完整分歧的接口。
5.2 平安方法:在Component中不去聲明Add和Remove辦法,那末子類的Leaf就不須要完成它,而是在Composit聲明一切用來治理子類對象的辦法。
5.3 兩種方法出缺點:關於通明方法,客戶端對葉節點和枝節點是分歧的,但葉節點其實不具有Add和Remove的功效,因此對它們的完成是沒成心義的;關於平安方法,葉節點無需在完成Add與Remove如許的辦法,然則關於客戶端來講,必需對葉節點和枝節點停止剖斷,為客戶真個應用帶來未便。
6. 形式總結
6.1 長處
6.1.1 使客戶端挪用簡略,它可以分歧應用組合構造或是個中單個對象,簡化了客戶端代碼。
6.1.2 輕易在組合體內增長對象部件。客戶端不用因參加了新的部件而更改代碼。有益於功效的擴大。
6.2 缺陷
6.2.1 須要決定應用通明方法照樣平安方法。
6.2.2 通明方法違反了面向對象的單一職責准繩;平安方法增長了客戶須要端剖斷的累贅。
6.3 實用場景
6.3.1 當想表達對象的部門-全體的條理構造時
6.3.3 願望用戶疏忽組合對象與單個對象的分歧,用戶將同一地應用組合構造中的一切對象時。