組合模式介紹

組合模式是把相似物件或方法組合成一組可被呼叫的結構樹物件的設計思路,
組合模式不只是可以運用于規則決策樹,還可以做服務包裝將不同的介面進行組合配置,對外提供服務能力,減少開發成本,
組合模式的主要解決的是一系列簡單邏輯節點或者擴展的復雜邏輯節點在不同結構的組織下,對于外部的呼叫是仍然可以非常簡單的,
組合模式的結構
- 組件 介面描述了樹中簡單專案和復雜專案所共有的操作,
- 葉節點 是樹的基本結構,它不包含子專案, 一般情況下,葉節點最侄訓完成大部分的實際作業,因為它們無法將作業指派給其他部分,
- 容器 又名組合,是包含葉節點或其他容器等子專案的單位,容器不知道其子專案所屬的具體類,它只通過通用的介面與其子專案互動,容器接收到請求后會將作業分配給自己的子專案,處理中間結果,然后將最終結果回傳客戶端,
- 客戶端 通過組件介面與所有專案互動,因此,客戶端能以相同方式與樹狀結構中的簡單或復雜專案互動,
組合模式的應用場景
- 當業務是需要實作樹狀物件結構,可以使用組合模式,
組合模式提供兩種共享公共介面的基本元素型別:簡單葉節點和復雜容器,容器中可以包含葉節點和其他容器,這樣就可以構建樹狀嵌套遞回物件結構,
- 當希望客戶端代碼以相同方式處理簡單和復雜元素,可以使用組合模式
組合模式中定義的所有元素共用同一個介面,正式由于這介面,客戶端不必在意其所使用的物件的具體類,
組合模式的優缺點
優點:
1、可以利用多型和遞回機制更方便地使用復雜樹結構
2、開閉原則,無需更改現有代碼,就可以在應用中添加新元素,使其成為物件樹的一部分,
缺點:
1、對于功能差異大的類,提供公共介面或許會有困難,
實作方式
1、確保應用的核心模型能夠以樹狀結構表示,嘗試將其分解為簡單元素和容器,其中容器必須同時包含簡單元素和其他容器,
2、宣告組件介面及其一系列方法,這些方法對簡單和復雜元素都有意義,
3、創建一個葉節點類表示簡單元素,程式中可以有多個不同的葉節點類,
4、創建一個容器類表示復雜元素,在該類中,創建一個陣列成員變數來存盤對于其子元素的參考,該陣列必須能夠同時保存葉節點和容器,因此請確保將其宣告為組合介面型別,
實作組件介面方法時,記住容器應該將大部分作業交給其子元素來完成,
5、在容器中定義添加和洗掉子元素的方法,
這些操作可在組件介面中宣告,會違背“介面隔離原則”,因為葉節點類中的這些方法為空,但是可以讓客戶端無差別地訪問所有元素,即使是組成樹狀結構的元素,
Demo
/// <summary>
/// 為簡單物件和復雜物件宣告了通用操作
/// </summary>
abstract class Component
{
public Component()
{
}
/// <summary>
/// 操作變數
/// </summary>
/// <returns></returns>
public abstract string Operation();
public virtual void Add(Component component)
{
throw new NotImplementedException();
}
public virtual void Remove(Component component)
{
throw new NotImplementedException();
}
/// <summary>
/// 是否是復合
/// </summary>
/// <returns></returns>
public virtual bool IsComposite()
{
return true;
}
}
/// <summary>
/// 葉
/// </summary>
class Leaf:Component
{
public override string Operation()
{
return "Leaf";
}
public override bool IsComposite()
{
return false;
}
}
/// <summary>
/// 復合物件(里面既包含葉又包含小復合物件)
/// </summary>
class Composite:Component
{
protected List<Component> _children = new List<Component>();
public override void Add(Component component)
{
this._children.Add(component);
}
public override void Remove(Component component)
{
this._children.Remove(component);
}
public override string Operation()
{
int i = 0;
string result = "包含的分支都有那些:";
foreach (var component in _children)
{
result += component.Operation();
if(i!=_children.Count-1)
{
result += "+";
}
i++;
}
return result + ")";
}
}
/// <summary>
/// 客戶端
/// </summary>
class Client
{
/// <summary>
/// 組件呼叫介面 葉子呼叫
/// </summary>
/// <param name="leaf"></param>
public void ClientCode(Component leaf)
{
Console.WriteLine("Result:"+leaf.Operation());
}
/// <summary>
/// 在基組件類中,客戶端可以與任何組件,簡單和復雜的物件互動,不依賴具體的類
/// </summary>
/// <param name="c1"></param>
/// <param name="c2"></param>
public void ClientCode2(Component c1,Component c2)
{
if (c1.IsComposite())
{
c1.Add(c2);
}
Console.WriteLine("Result:"+c1.Operation());
}
}
class Program
{
static void Main(string[] args)
{
Client client = new Client();
Leaf leaf = new Leaf();
Console.WriteLine("呼叫葉子......");
client.ClientCode(leaf);
Console.WriteLine("---------------");
Composite tree = new Composite();
Composite branch1 = new Composite();
branch1.Add(new Leaf());
branch1.Add(new Leaf());
Composite branch2 = new Composite();
branch2.Add(new Leaf());
tree.Add(branch1);
tree.Add(branch2);
Console.WriteLine("呼叫復雜物件......");
client.ClientCode(tree);
Console.WriteLine("---");
client.ClientCode2(tree,leaf);
Console.ReadKey();
}
}

從計算結果可以看出,當第一次只呼叫葉子時,結果就只顯示葉子,也就是簡單元素,當第二次宣告實體化復雜容器(包含葉子和別的容器)時,輸出結果也可以把所有宣告實體的容器中的所有葉子和子容器都輸出顯示,
其實對于我們業務來說,需要把握好業務的邏輯看到底需要并適合那種模式,這樣才能不為了模式而模式代碼,
小寄語
人生短暫,我不想去追求自己看不見的,我只想抓住我能看的見的,
我是阿輝,感謝您的閱讀,如果對你有幫助,麻煩點贊、轉發 謝謝,
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/294097.html
標籤:.NET技术
上一篇:【設計模式】裝飾器
下一篇:【設計模式】裝飾器
