组合模式(Composite Design Pattern)
组合模式将一组对象组织成树形结构,将单个对象和组合对象都看做树中的节点,以统一处理逻辑,并且它利用树形结构的特点,递归地处理每个子树,依次简化代码实现。
结构图:
角色:
- 抽象节点(Component):
- 透明模式下把所有行为都再放抽象节点中,让不同层次的结构都具备一致行为
- 安全组合模式是只规定各个节点的最基础的一致行为,而把组合节点的方法放到节点自身中。
- 叶子节点(Leaf):树的基本结构,它不包含子项目。
- 树枝节点(Composite):含叶节点的单位,树枝不知道其子项目所属的具体类, 它只通过通用的组件接口与其子项目交互。
适用场景:
- 需要对象表达有层次的结构时。
优点:
- 利用多态和递归机制更方便地使用复杂树结构。
- 无需更改现有代码就可以在应用中添加新元素。
缺点
- 设计更加复杂,增加代码复杂度。
代码(C#)
透明模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
|
public abstract class Component { public string Name { get; set; }
public Component(string name) { Name = name; }
public abstract void Add(Component company); public abstract void Remove(Component company); public abstract void Get(int index); }
public class Composite : Component { private List<Component> c = new();
public Composite(string name) : base(name) { }
public override void Add(Component company) { c.Add(company); }
public override void Remove(Component company) { c.Remove(company); }
public override void Get(int index) { Console.WriteLine($"{new string('-', index)}{Name}"); foreach (var item in c) { item.Get(index + 2); } } }
public class Leaf : Component { public Leaf(string name) : base(name) { }
public override void Add(Component company) { throw new NotImplementedException(); }
public override void Remove(Component company) { throw new NotImplementedException(); }
public override void Get(int index) { Console.WriteLine($"{new string('-', index)}{Name}"); } }
var component = new Composite("技术部");
var kaifa = new Composite("开发部"); component.Add(kaifa);
var xiaoming = new Leaf("小明"); kaifa.Add(xiaoming);
var ceshi = new Composite("测试"); component.Add(ceshi); var xiaohong = new Leaf("小红"); ceshi.Add(xiaohong);
component.Get(2);
|
安全模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
|
public abstract class Component { public string Name { get; set; }
public Component(string name) { Name = name; }
public abstract void print(int index); }
public class Composite : Component { private List<Component> c = new();
public Composite(string name) : base(name) { }
public void Add(Component company) { c.Add(company); }
public void Remove(Component company) { c.Remove(company); }
public override void print(int index) { Console.WriteLine($"{new string('-', index)}{Name}"); foreach (var item in c) { item.print(index + 2); } }
public Component Get(int index) { return c[index]; } }
public class Leaf : Component { public Leaf(string name) : base(name) { }
public Component Get() { return this; }
public override void print(int index) { Console.WriteLine($"{new string('-', index)}{Name}"); } }
|
最后
使用组合模式的前提在于,业务场景必须能够表示成树形结构。所以,组合模式的应用场景也比较局限,它并不是一种很常用的设计模式。