組合模式(Composite Pattern)

1、 組合(Composite)模式

組合模式容許你將對象組合成樹形結構來表現」部分-總體「的層次結構,使得客戶以一致的方式處理單個對象以及對象的組合。下面咱們用繪製的例子來詳細介紹組合模式,圖形能夠由一些基本圖形元素組成(如直線,圓等),也能夠由一些複雜圖形組成(由基本圖形元素組合而成),爲了使客戶對基本圖形和複雜圖形的調用保持一致,咱們使用組合模式來達到整個目的。設計模式

組合模式實現的最關鍵的地方是——簡單對象和複合對象必須實現相同的接口。這就是組合模式可以將組合對象和簡單對象進行一致處理的緣由。安全

2、組合模式的結構

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

    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在組合中標識葉節點對象,葉節點沒有子節點。post

    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。this

    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);
            }
        }
    }

客戶端代碼:spa

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

結果顯示:設計

3、透明方式與安全方式code

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

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

 

4、組合模式的優缺點

優勢:

  1. 組合模式使得客戶端代碼能夠一致地處理對象和對象容器,無需關係處理的單個對象,仍是組合的對象容器。
  2. 將」客戶代碼與複雜的對象容器結構「解耦。
  3. 能夠更容易地往組合對象中加入新的構件。

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

 

5、組合模式的使用場景

在如下狀況下應該考慮使用組合模式:

  1. 須要表示一個對象總體或部分的層次結構。
  2. 但願用戶忽略組合對象與單個對象的不一樣,用戶將統一地使用組合結構中的全部對象。
相關文章
相關標籤/搜索