設計模式-結構型-組合模式

  • 2019 年 10 月 3 日
  • 筆記

組合模式(Composite):

定義:

  組合模式又叫部分整體模式,它是一種將對象組合成樹狀的層次結構模式,用來表示”部分-整體”的關係,使用戶對單個對象和組合對象具有一致的訪問性。

組合模式的角色:

  1)抽象構建(Component):它的主要作用是為樹葉構件和樹枝構件聲明公共介面,並實現它們的默認行為。在透明式的組合模式中抽象構件還聲明訪問和管理子類的介面;在安全式的組合模式中不聲明訪問和管理子類的介面,管理工作由樹枝構件完成。

  2)樹葉構件(Leaf):是組合中的葉節點對象,它沒有子節點,用於實現抽象構件角色中 聲明的公共介面。

  3)樹枝構件(Composite):是組合中的分支節點對象,它有子節點。它實現了抽象構件角色中聲明的介面,它的主要作用是存儲和管理子部件,通常包含 Add()、Remove()、GetChild() 等方法。

  

 1 internal class Program   2 {   3     private static void Main(string[] args)   4     {   5         // Create a tree structure   6         Composite root = new Composite("root");   7         root.Add(new Leaf("Leaf A"));   8         root.Add(new Leaf("Leaf B"));   9  10         Composite comp = new Composite("Composite X");  11         comp.Add(new Leaf("Leaf XA"));  12         comp.Add(new Leaf("Leaf XB"));  13  14         root.Add(comp);  15         root.Add(new Leaf("Leaf C"));  16  17         // Add and remove a leaf  18         Leaf leaf = new Leaf("Leaf D");  19         root.Add(leaf);  20         root.Remove(leaf);  21  22         // Recursively display tree  23         root.Display(1);  24     }  25 }  26  27 public abstract class Component  28 {  29     protected string _name;  30  31     public Component(string name)  32     {  33         this._name = name;  34     }  35  36     public abstract void Add(Component c);  37  38     public abstract void Remove(Component c);  39  40     public abstract void Display(int depth);  41 }  42  43 public class Leaf : Component  44 {  45     public Leaf(string name)  46         : base(name)  47     {  48     }  49  50     public override void Add(Component c)  51     {  52         Console.WriteLine("Cannot add to a leaf");  53     }  54  55     public override void Remove(Component c)  56     {  57         Console.WriteLine("Cannot remove from a leaf");  58     }  59  60     public override void Display(int depth)  61     {  62         Console.WriteLine(new String('-', depth) + _name);  63     }  64 }  65  66 public class Composite : Component  67 {  68     private List<Component> _children = new List<Component>();  69  70     public Composite(string name)  71         : base(name)  72     {  73     }  74  75     public override void Add(Component component)  76     {  77         _children.Add(component);  78     }  79  80     public override void Remove(Component component)  81     {  82         _children.Remove(component);  83     }  84  85     public override void Display(int depth)  86     {  87         Console.WriteLine(new String('-', depth) + _name);  88  89         foreach (Component component in _children)  90         {  91             component.Display(depth + 2);  92         }  93     }  94 }

 極簡版如下,將顯示部分可以拿到客戶端進行:

 1 internal class Program   2 {   3     private static void Main(string[] args)   4     {   5         // Create a tree structure   6         Component root = new Component("root");   7         root.Add(new Component("Leaf A"));   8         root.Add(new Component("Leaf B"));   9  10         Component comp = new Component("Composite X");  11         comp.Add(new Component("Leaf XA"));  12         comp.Add(new Component("Leaf XB"));  13  14         root.Add(comp);  15         root.Add(new Component("Leaf C"));  16  17         // Add and remove a leaf  18         Component leaf = new Component("Leaf D");  19         root.Add(leaf);  20         root.Remove(leaf);  21  22         // 由客戶端顯示,Component只進行組合  23     }  24 }  25  26 public class Component  27 {  28     protected string _name;  29     private List<Component> _children = new List<Component>();  30  31     public Component(string name)  32     {  33         this._name = name;  34     }  35  36     public void Add(Component c)  37     {  38         _children.Add(c);  39     }  40  41     public void Remove(Component c)  42     {  43         _children.Remove(c);  44     }  45  46     public List<Component> GetChild()  47     {  48         return _children;  49     }  50 }

是不是恍然大悟,就是我們在做許可權管理的時候用到的一對多的關係。

組合模式的優缺點:

  優點:

    1)組合模式使得客戶端程式碼可以一致地處理單個對象和組合對象,無須關心自己處理的單個對象還是組合對象,這簡化了客戶端程式碼;

    2)更容易在組合體內加入新的對象,客戶端不會因為加入新的對象而更改源程式碼,滿足OCP原則。

  缺點:

    1)設計較複雜,客戶端需要花更多的時間理清類之間的層次關係;

    2)不容易限制容器中的構件;

    3)不容易用繼承的方法來增加構件的新功能。

參考:https://www.cnblogs.com/libingql/p/3496345.html