将对象组合成树形结构以表示“部分-整体”的层次结构。Composite模式使得用户对单个对象和组合对象的使用具有一致性。
Composite模式采用树形结构来实现普遍存在的对象容器,从而将“一对多”的关系转化“一对一”的关系,使得客户代码可以一致地处理对象和对象容器,无需关心处理的是单个的对象,还是组合的对象容器。将“客户代码与复杂的对象容器结构”解耦是Composite模式的核心思想,解耦之后,客户代码将与纯粹的抽象接口——而非对象容器的复内部实现结构——发生依赖关系,从而更能“应对变化”。
Composite模式中,是将“Add和Remove等和对象容器相关的方法”定义在“表示抽象对象的Component类”中,还是将其定义在“表示对象容器的Composite类”中,是一个关乎“透明性”和“安全性”的两难问题。这里有可能违背面向对象的“单一职责原则”,但是对于这种特殊结构,这又是必须付出的代价。
类关系图如下:
通过CompositionOperater对象将其他类的操作组合起来,使客户端能够像使用一般对象一样使用组合对象:
1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4
5
6 using System.Collections;
7
8 namespace CompositePatternSam
9 {
10 public class CompositionOperater : DoSomething
11 {
12 private List<DoSomething> list = new List<DoSomething>();//组合起来作为容器
13 public override void Work()
14 {
15 // throw new Exception("The method or operation is not implemented.");
16 foreach(DoSomething obj in list ){
17 obj.Work();//遍历所有容器的所有对象
18 }
19 }
20
21 public void Add(DoSomething obj)
22 {//添加对象
23 list.Add(obj);
24
25 }
26
27 public void Remove(DoSomething obj) {
28 //移除对象
29 list.Remove(obj);
30 }
31 }
32 }
33
2 using System.Collections.Generic;
3 using System.Text;
4
5
6 using System.Collections;
7
8 namespace CompositePatternSam
9 {
10 public class CompositionOperater : DoSomething
11 {
12 private List<DoSomething> list = new List<DoSomething>();//组合起来作为容器
13 public override void Work()
14 {
15 // throw new Exception("The method or operation is not implemented.");
16 foreach(DoSomething obj in list ){
17 obj.Work();//遍历所有容器的所有对象
18 }
19 }
20
21 public void Add(DoSomething obj)
22 {//添加对象
23 list.Add(obj);
24
25 }
26
27 public void Remove(DoSomething obj) {
28 //移除对象
29 list.Remove(obj);
30 }
31 }
32 }
33
其他对象类代码:
1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4
5 namespace CompositePatternSam
6 {
7 public abstract class DoSomething
8 {
9 public abstract void Work();
10 }
11 }
12
13 using System;
14 using System.Collections.Generic;
15 using System.Text;
16
17 namespace CompositePatternSam
18 {
19 public class DoSomethingA:DoSomething
20 {
21
22 public override void Work()
23 {
24 Console.WriteLine("do something work A!!");
25 Console.WriteLine();
26 }
27 }
28 }
29
30 using System;
31 using System.Collections.Generic;
32 using System.Text;
33
34 namespace CompositePatternSam
35 {
36 public class DoSomethingB:DoSomething
37 {
38 public override void Work()
39 {
40 Console.WriteLine("do something work B!!");
41 Console.WriteLine();
42 }
43 }
44 }
45
2 using System.Collections.Generic;
3 using System.Text;
4
5 namespace CompositePatternSam
6 {
7 public abstract class DoSomething
8 {
9 public abstract void Work();
10 }
11 }
12
13 using System;
14 using System.Collections.Generic;
15 using System.Text;
16
17 namespace CompositePatternSam
18 {
19 public class DoSomethingA:DoSomething
20 {
21
22 public override void Work()
23 {
24 Console.WriteLine("do something work A!!");
25 Console.WriteLine();
26 }
27 }
28 }
29
30 using System;
31 using System.Collections.Generic;
32 using System.Text;
33
34 namespace CompositePatternSam
35 {
36 public class DoSomethingB:DoSomething
37 {
38 public override void Work()
39 {
40 Console.WriteLine("do something work B!!");
41 Console.WriteLine();
42 }
43 }
44 }
45
客户端代码:通过先ADD()方法对象进行操作,然后remove()方法移除一个对象后再次操作:
1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4
5 namespace CompositePatternSam
6 {
7 class Program
8 {
9 static void Main(string[] args)
10 {
11 CompositionOperater oper = new CompositionOperater();
12 oper.Add(new DoSomethingA());
13 DoSomethingB b = new DoSomethingB();
14 oper.Add(b);
15 oper.Add(new DoSomethingC());
16 oper.Work();
17 Console.ReadLine();
18 Console.WriteLine("*******************************");
19 oper.Remove(b);
20 oper.Work();
21 Console.ReadLine();
22 }
23 }
24 }
25
2 using System.Collections.Generic;
3 using System.Text;
4
5 namespace CompositePatternSam
6 {
7 class Program
8 {
9 static void Main(string[] args)
10 {
11 CompositionOperater oper = new CompositionOperater();
12 oper.Add(new DoSomethingA());
13 DoSomethingB b = new DoSomethingB();
14 oper.Add(b);
15 oper.Add(new DoSomethingC());
16 oper.Work();
17 Console.ReadLine();
18 Console.WriteLine("*******************************");
19 oper.Remove(b);
20 oper.Work();
21 Console.ReadLine();
22 }
23 }
24 }
25
显示结果如下:
*************************************************************************************