設計模式學習總結-組合模式(Composite Method)

來源:互聯網
上載者:User

問題:
在某些情況下,
一類具有“容器特徵”的對象在充當對象的同時,又是其他對象的容器的情況,比如樹狀結構的對象,如果客戶過多地依賴於對象容器複雜的內部實現結構,對象容器內部實現結構的變化將引起客戶代碼的頻繁變化。如何將“客戶代碼與複雜的對象容器結構”解耦?讓對象容器自己來實現自身的複雜結構,從而使得客戶代碼就像處理簡單對象一樣來處理複雜的對象容器?
定義:
組合(Composite )模式是構造型的設計模式之一,是指將對象組合成樹形結構以表示“部分-整體”的階層,組合模式使得客戶對單個對象和組合對象的使用具有一致性。

意圖:
提供一個Component角色,它定義了訪問與管理組件(部分-整體)的通用介面一般包含Add(),Remove()等方法。定義一個使用者儲存子組件的Composite角色,他實現了Component角色提供訪問與管理組件的所有方法。並維護了一個Component角色的引用列表,用於管理維護所有的子組件。這樣使得基礎對象可以被組合成更複雜的組合對象,而這個組合對象又可以被組合,這樣不斷地遞迴下去就形成了一個樹形結構的複雜物件。組合模式就是採用樹形結構來實現普遍存在的對象容器,從而將一對多的關係轉化一對一的關係,使得客戶代碼可以一致地處理對象和對象容器,無需關心處理的是單個的對象,還是組合的對象容器。將客戶程式與對象內部實現解耦,讓對象容器自己來實現自身的複雜結構,解耦後,客戶程式只能對象上層的介面發生關係。

參與者:
•抽象組件角色(Component):
是組合中的對象聲明介面,在適當的情況下,實現所有類共有介面的預設行為。聲明一個介面用於訪問和管理Component子組件。
•葉組件角色(Leaf):
在組合中表示分葉節點對象沒有子節點,實現抽象組件角色聲明的介面。
•子組件角色(Composite):
在組合中表示分支節點對象,用來儲存子組件,有子節點,實現抽象組件角色聲明的介面如增加(add)和刪除(remove)等。
UML:

代碼說明: 

/// <summary>
/// 抽象組件角色(Component)
/// </summary>
public abstract class Component
{
    public string Name { get; set; }
    public abstract void Add(Component component);
    public abstract void Remove(Component component);
    public abstract void Show();
}
/// <summary>
/// 葉組件角色(Leaf)
/// </summary>
public class Leaf : Component
{
    public override void Add(Component component)
    {
        System.Console.WriteLine("我是一個葉子節點,不能添加子物件");
    }
    public override void Remove(Component component)
    {
        System.Console.WriteLine("我是一個葉子節點,沒有子物件");
    }
    public override void Show()
    {
        System.Console.WriteLine("我是一個葉子節點。");
    }
}
/// <summary>
/// 子組件角色(Composite)
/// </summary>
public class CompositeClass : Component
{
    List<Component> list = new List<Component>();
    public override void Add(Component component)
    {
        list.Add(component);
    }
    public override void Remove(Component component)
    {
        list.Remove(component);
    }
    public override void Show()
    {
        foreach (var s in list)
        {
            System.Console.WriteLine(String.Format("我是{0}節點。",s.Name));
        }
    }
}
/// <summary>
/// 用戶端測試
/// </summary>
public void CompositeTest()
{
    Component obj = new CompositeClass();
    obj.Name = "我是個節點";
    Component obj1 = new CompositeClass() { Name = "我還是一個節點" };
    Component obj2 = new CompositeClass() { Name = "我還是一個節點" };
    obj2.Add(new Leaf() { Name="我是一個葉子節點" });
    obj.Add(obj1);
    obj.Add(obj2);
}

優點:
•客戶代碼與複雜的對象容器結構解耦,讓對象容器自己來實現自身的複雜結構。添加或移除對象不必修改用戶端代碼。
•單個對象和組合對象具有一致性介面,所以使用者不必關係自己處理的是單個對象還是整個組合結構,這就簡化了用戶端代碼。

適用場合:
•表示對象的部分-整體階層(樹形結構)。
•希望使用者忽略組合對象與單個對象的不同,使用者將統一地使用組合結構中的所有對象。

透明方式與安全方式:
透明方式(用戶端不關係,不知道使用的是Composite還是Leaf):
在Component中聲明所有用來來管理子物件的方法,包含Add(),Remove()等,這樣喜歡Component介面所有的子物件都具備Add(),Remove()等,這樣能達到GoF所說的“單個對象和組合對象的使用具有一致性”可是對於Leaf節點不具備Add(),Remove()等操作,這個實現是沒有意義的。
安全方式:
在Composite中聲明所有用來來管理子物件的方法,不在Leaf中定義和實現不需要的操作,這樣會使Composite與Leaf不具有相同的介面,用戶端調用需要做相應的判斷。
GoF比較傾向於:以不遵守單一責任原則換取透明性,讓Client將組合和分葉節點具有一致性。
在實現組合模式時,有很多設計上的折衷。要根據需求平衡透明性和安全性。 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.