1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6
7 namespace DesignPattern.StructuralPattern
8 {
9 #region 组合模式要点
10
11 //定义:将对象组合成树形结构来表示 部分-整体的层次结构,使客户端能够使用相同的方式来处理叶节点和容器
12 //组合模式实现的最关键的地方是——简单对象和复合对象必须实现相同的接口
13 //优点:
14 //1.是客户端忽略单个对象和对象容器的区别,使用一致的方式处理
15 //2.可以更容易向组合对象添加新的组件
16 //
17 //使用场景:1.实现树形结构对象 2.使用一致的方式处理简单对象和复杂容器
18 /*
19 实现方式:
20 1.确保应用的核心模型能够以树状结构表示。 尝试将其分解为简单元素和容器。
21 容器必须能够同时包含简单元素和其他容器。
22 2.声明组件接口及其一系列方法, 这些方法对简单和复杂元素都有意义
23 透明模式和安全模式:可将叶节点不需要的行为仅在容器中保留,抽象接口仅定义共同的抽象行为。
24 3.创建一个叶节点类表示简单元素。 程序中可以有多个不同的叶节点类。
25 4.创建一个容器类表示复杂元素。 在该类中, 创建一个数组成员变量来存储对于其子元素的引用。
26 该数组必须能够同时保存叶节点和容器, 因此请确保将其声明为组合接口类型。
27 5.实现组件接口方法时, 记住容器应该将大部分工作交给其子元素来完成。
28 6.最后, 在容器中定义添加和删除子元素的方法。
29 这些操作可在组件接口中声明。 这会违反接口隔离原则,因为叶节点类中的某些方法会为空。
30 但这可以让客户端无差别地访问所有元素,即使是组成树状结构的元素。
31 */
32
33 #endregion
34 public abstract class CompositePattern
35 {
36 public string Name { get; set; }
37 public CompositePattern(string name)
38 {
39 Name = name;
40 }
41 //规定叶节点和容器的行为
42 public abstract string Operation();
43 public abstract void AddOperation(CompositePattern composite);
44 public abstract void DeleteOperation(CompositePattern composite);
45
46 public virtual bool IsComposite()
47 {
48 return true;
49 }
50 }
51
52 public class Leaf : CompositePattern
53 {
54 public Leaf(string name) :base(name)
55 {
56 }
57
58 //叶节点是最小单位,不能增删新的行为
59 public override void AddOperation(CompositePattern composite)
60 {
61 throw new NotImplementedException();
62 }
63
64 public override void DeleteOperation(CompositePattern composite)
65 {
66 throw new NotImplementedException();
67 }
68
69 public override string Operation()
70 {
71 return $"Leaf_{Name} ";
72 }
73 }
74
75 public class Composite : CompositePattern
76 {
77 public Composite(string name) : base(name)
78 {
79 }
80
81 //保存叶节点和容器
82 private List<CompositePattern> composites = new List<CompositePattern>();
83 public override void AddOperation(CompositePattern composite)
84 {
85 composites.Add(composite);
86 }
87
88 public override string Operation()
89 {
90 StringBuilder sb = new StringBuilder(48);
91 sb.Append("Branch(");
92 foreach (var item in composites)
93 {
94 if (item.IsComposite())
95 {
96 sb.Append($"Branch_{Name} ");
97 }
98
99 sb.Append(item.Operation());
100 }
101 sb.Append(")");
102 return sb.ToString();
103 }
104
105 public override void DeleteOperation(CompositePattern composite)
106 {
107 composites.Remove(composite);
108 }
109
110 public override bool IsComposite()
111 {
112 return true;
113 }
114 }
115 }