天天看點

極速了解設計模式系列:5.組合模式(Composite Pattern)

四個角色:部件抽象接口角色(Component)、葉角色(Leaf)、組合類角色(Composite)、用戶端角色(Client)

        部件抽象接口角色(Component):定義組合類對象的公共行為、屬性和管理子部件的方法接口。

        葉角色(Leaf):實作Component的公共行為,但是無法管理子部件,為最終葉節點。

        組合類角色(Composite):實作Component的公共行為,可以管理子節點(增、删、查)。

        用戶端角色(Client):通過Component控制整棵組合對象樹。

         實作思路:一棵樹,分為葉節點和主幹節點,通過一個統一的接口可以往下添加節點和删除節點。

 類圖:

<a target="_blank" href="http://blog.51cto.com/attachment/201204/155407950.jpg"></a>

        應用場景:Silverlight中一個Canvas名為Layout,需要有很多行,第一行 是一個TextBox,第二行是一個RichTextBox,第三行是RadioButton,第四行是一個複雜的組合控件名為complex其内部有 RadioButtonA、ComboBoxB、TextBoxC三個子控件。

        分析:這裡實際上可以看做是一棵樹型結構的容器Layout,内部有4個控件,其中3個簡單控件是葉節點,最後一個複雜控件是主幹,主幹下面還有3個葉片節點。

        下面我們在控制台程式去示範一下如何使用Composite Pattern:

        一、部件抽象接口角色(Component)

//部件抽象接口角色:Component 

abstract class ControlComponent 

    public string ControlName { get; set; } 

    public double Width { get; set; } 

    public double Height { get; set; } 

    public int AllowInputNum { get; set; } 

    abstract public void AddNode(ControlComponent con); 

    abstract public void RemoveNode(ControlComponent con); 

    abstract public void ShowNodeInfo(); 

        二、葉角色(Leaf)

//葉角色:Leaf 

 class ControlLeaf : ControlComponent 

 { 

     //葉角色沒有子節點,故不能添加删除子節點 

     public override void AddNode(ControlComponent con) 

     { 

         Console.WriteLine("葉類無法添加子節點。"); 

     } 

     public override void RemoveNode(ControlComponent con) 

         Console.WriteLine("葉類無法移出子節點。"); 

     //顯示子節點資訊的方法 

     public override void ShowNodeInfo() 

         Console.WriteLine("___控件名:" + ControlName + " 控件寬度:" + Width + " 控件高度:" + Height + " 控件允許輸入:" + AllowInputNum); 

 } 

        三、組合類角色(Composite)

//組合類:Composite(主幹類) 

 class ControlComposite : ControlComponent 

     //子節點的容器(可以是葉節點,葉可以是下一節主幹) 

     private List&lt;ControlComponent&gt; controlList = new List&lt;ControlComponent&gt;(); 

     //添加和删除子節點 

         controlList.Add(con); 

         controlList.Remove(con); 

     //顯示子節點 

         Console.WriteLine("控件名:" + ControlName + " 控件寬度:" + Width + " 控件高度:" + Height + " 控件允許輸入:" + AllowInputNum); 

         //遞歸顯示其子節點樹 

         foreach (ControlComponent c in controlList) 

         { 

             c.ShowNodeInfo(); 

         } 

        四、用戶端角色(Client)

//用戶端:Client 

class Program 

    static void Main(string[] args) 

    { 

        ControlComposite controlLayout = new ControlComposite() { ControlName = "Layout", Height = 300, Width = 300 }; 

        controlLayout.AddNode(new ControlLeaf() { ControlName = "___TextBox", Height = 30, Width = 180, AllowInputNum = 50 }); 

        controlLayout.AddNode(new ControlLeaf() { ControlName = "___RichTextBox", Height = 35, Width = 220, AllowInputNum = 1000 }); 

        controlLayout.AddNode(new ControlLeaf() { ControlName = "___RadioButton", Height = 25, Width = 300, AllowInputNum = 1 }); 

        ControlComposite complexControl = new ControlComposite() { ControlName = "complex", Height = 96, Width = 300 }; 

        complexControl.AddNode(new ControlLeaf() { ControlName = "___RadioButtonA", Height = 33, Width = 180, AllowInputNum = 50 }); 

        complexControl.AddNode(new ControlLeaf() { ControlName = "___ComboBoxB", Height = 33, Width = 100 }); 

        complexControl.AddNode(new ControlLeaf() { ControlName = "___TextBoxC", Height = 30, Width = 100 }); 

        controlLayout.AddNode(complexControl); 

        // controlLayout.RemoveNode(complexControl); 

        controlLayout.ShowNodeInfo(); 

        Console.ReadLine(); 

    } 

本文轉自程興亮 51CTO部落格,原文連結:http://blog.51cto.com/chengxingliang/826952

繼續閱讀