组合模式(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
来源:https://www.cnblogs.com/az4215/p/11602936.html