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 願望用戶疏忽組合對象與單個對象的分歧,用戶將同一地應用組合構造中的一切對象時。