2.4設計模式之組合模式(Composite)

2.4.1 模式意圖:

在處理樹形結構數據時,通常必須區分葉節點和分支節點。這使代碼更復雜,也更容易出錯。組合模式模糊了葉節點和分支節點的概念,可以使葉節點和分支節點以單一對象的方式統一處理,且所有節點對象均具有相似的功能。

2.4.2 模式概念:

它屬于結構型模式,將對象組合成樹形結構以表示“部分-整體”的層次結構。組合模式使得用戶對單個對象和組合對象的使用具有一致性。

2.4.3 模式元素:

  • 節點抽象(CompsiteBase)
  • 葉子節點(Leaf)
  • 復合節點(Composite)

2.4.4 代碼示例:

示例相對簡單,就是一個樹狀的結構,一個主干,然后就是分支,每個分支可能是葉子節點,也可能是含有子分支的節點。

A.創建一個節點的抽象基類 ,也就是每個節點基類

    public abstract class CompsiteBase
    {
        protected string name;

        public CompsiteBase(string name)
        {
            this.name = name;
        }

        public abstract void Add(CompsiteBase c);
        public abstract void Remove(CompsiteBase c);
        public abstract void Display(int depth);
    }

B.葉子節點,也就是不含子節點的分支

public class Leaf : CompositeBase
{
    public Leaf(string name) : base(name) { }

    public override void Add(CompositeBase c)
    {
        Debug.Log("Cannot add to a leaf");
    }

    public override void Remove(CompositeBase c)
    {
        Debug.Log("Cannot remove from a leaf");
    }

    public override void Display(int depth)
    {
        Debug.Log(new string('-', depth) + name);
    }
}

C.含有子節點的分支

public class Composite : CompositeBase
{
    private List<CompsiteBase> children = new List<CompsiteBase>();

    public Composite(string name) : base(name) { }

    public override void Add(CompositeBase c)
    {
        children.Add(c);
    }

    public override void Remove(CompositeBase c)
    {
        children.Remove(c);
    }

    public override void Display(int depth)
    {
        Debug.Log(new String('-', depth) + name);

        foreach (CompositeBase composite in children)
        {
            compsite.Display(depth + 2);
        }
    }
}

示例調用

    void Start()
    {
        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);
    }

2.4.5 寫法對比:

2.4.6 模式分析:

通過CompositeBase接口來統一處理LeafComposite對象: Leaf對象直接執行請求,而Composite對象將請求以遞歸的方式向下傳遞到樹結構的子節點。這使得類更易于實現、更改、測試和重用。

組合模式也分為安全模式透明模式

  • 安全模式:在抽象基類中沒有提供 Add Remove等管理子節點的函數。
    優點:不必實現不需要的相關函數。
    缺點:需要區分葉子節點和含有子節點的分支,進行分別調用。
  • 透明模式:與安全模式相反,含有對應管理子節點的函數。
    優點:可以統一的調用。
    缺點:容易錯誤調用相關的管理函數而引發異常。

2.4.7 應用場景:

  • 整體部分的層次為樹結構,且需要統一對待部分和整體對象。

2.4.8 小結:

當你發現需求是體現部分與整體層次結構時,以及你希望用戶可以忽律組合對象與單個對象的不同,統一地使用組合結構中的所有對象,就可以考慮使用組合模式了。


更多設計模式詳見:設計模式全家桶

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容