組合模式(Composite Pattern)


一、 組合(Composite)模式

組合模式允許你將對象組合成樹形結構來表現”部分-整體“的層次結構,使得客戶以一致的方式處理單個對象以及對象的組合。下面我們用繪制的例子來詳細介紹組合模式,圖形可以由一些基本圖形元素組成(如直線,圓等),也可以由一些復雜圖形組成(由基本圖形元素組合而成),為了使客戶對基本圖形和復雜圖形的調用保持一致,我們使用組合模式來達到整個目的。

組合模式實現的最關鍵的地方是——簡單對象和復合對象必須實現相同的接口。這就是組合模式能夠將組合對象和簡單對象進行一致處理的原因。

二、組合模式的結構

Component為組合中的對象聲明接口,在適當情況下,實現所有類共有接口的默認行為。聲明一個接口用於訪問和管理Component的子部件。

    abstract class Component
    {
        protected string name;

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

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

Leaf在組合中標識葉節點對象,葉節點沒有子節點。

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

        public override void Add(Component c)
        {
            Console.WriteLine("Cannot add to a leaf");
        }

        public override void Remove(Component c)
        {
            Console.WriteLine("Cannot remove from a leaf");
        }

        public override void Display(int depth)
        {
            Console.WriteLine(new String('-', depth) + name);
        }
    }

Composite定義有枝節點行為,用來存儲子部件,在Composite接口中實現與子部件有關的操作,比如增加ADD和刪除Remove。

    class Composite : Component
    {
        private List<Component> children = new List<Component>();

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

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

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

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

            foreach (Component component in children)
            {
                component.Display(depth + 2);
            }
        }
    }

客戶端代碼:

   class Program
    {
        static void Main(string[] args)
        {
            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);

            Console.Read();
        }
    }

結果顯示:

三、透明方式與安全方式

透明方式:在Ccomponent中聲明所有用來管理子對象的方法,其中包括ADD,Remove等。這樣實現Component接口的所有子類都具備了Add,Remove。這樣做的好處就是葉節點和枝節點對於外界沒有區別,他們具備完全一致的行為接口。但為題也很明顯,因為Leaf類本身不具備Add(),Remove()方法功能,所以實現他是沒有意義。

安全方式:在Component接口中不去聲音Add,Remove 方法,那么子類的Left就不需要去實現它,而是在Compostie生硬所有用來管理子類對象的方法,這樣做就不會出現上面的問題,不過由於不夠透明,所有樹葉和樹枝類將不具有相同的接口,客戶端調用需要做相應的判斷,帶來的不方便。

 

四、組合模式的優缺點

優點:

  1. 組合模式使得客戶端代碼可以一致地處理對象和對象容器,無需關系處理的單個對象,還是組合的對象容器。
  2. 將”客戶代碼與復雜的對象容器結構“解耦。
  3. 可以更容易地往組合對象中加入新的構件。

缺點:使得設計更加復雜。客戶端需要花更多時間理清類之間的層次關系。(這個是幾乎所有設計模式所面臨的問題)。

 

五、組合模式的使用場景

在以下情況下應該考慮使用組合模式:

  1. 需要表示一個對象整體或部分的層次結構。
  2. 希望用戶忽略組合對象與單個對象的不同,用戶將統一地使用組合結構中的所有對象。

 


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
  © 2014-2022 ITdaan.com 联系我们: