中介者模式
中介者模式结构:
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.BehavioralPattern
8 {
9 #region 中介者模式模式
10 //定义: 中介者模式,定义了一个中介对象来封装一系列对象之间的交互关系。
11 //
12 //核心思想:
13 //中介者模式建议你停止组件之间的直接交流并使其相互独立。
14 //这些组件必须调用特殊的中介者对象, 通过中介者对象重定向调用行为, 以间接的方式进行合作。
15 //最终,组件仅依赖于一个中介者类, 无需与多个其他组件相耦合。
16 //
17 //使用场景:
18 //1.当一些对象和其他对象紧密耦合以致难以对其进行修改时
19 //2.当组件因过于依赖其他组件而无法在不同应用中复用时
20 //3.如果为了能在不同情景下复用一些基本行为, 导致你需要被迫创建大量组件子类时,
21 //
22 //
23 /*
24 * 实现方式:
25 1.找到一组当前紧密耦合, 且提供其独立性能带来更大好处的类 (例如更易于维护或更方便复用)。
26
27 2.声明中介者接口并描述中介者和各种组件之间所需的交流接口。
28 在绝大多数情况下, 一个接收组件通知的方法就足够了。
29 如果你希望在不同情景下复用组件类, 那么该接口将非常重要。
30 只要组件使用通用接口与其中介者合作, 你就能将该组件与不同实现中的中介者进行连接。
31
32 3.实现具体中介者类。 该类可从自行保存其下所有组件的引用中受益。
33
34 4.你可以更进一步, 让中介者负责组件对象的创建和销毁。
35 此后, 中介者可能会与工厂或外观类似。
36
37 5.组件必须保存对于中介者对象的引用。
38 该连接通常在组件的构造函数中建立, 该函数会将中介者对象作为参数传递。
39
40 6.修改组件代码, 使其可调用中介者的通知方法, 而非其他组件的方法。
41 然后将调用其他组件的代码抽取到中介者类中, 并在中介者接收到该组件通知时执行这些代码。
42 */
43 #endregion
44
45 //中介者 (Mediator) 接口声明了与组件交流的方法, 但通常仅包括一个通知方法。
46 //组件可将任意上下文 (包括自己的对象) 作为该方法的参数, 只有这样接收组件和发送者类之间才不会耦合。
47 public interface IMediatorPattern
48 {
49 void Notify(BaseConponent sender, string param);
50 }
51
52 //具体中介者 (Concrete Mediator) 封装了多种组件间的关系。
53 //具体中介者通常会保存所有组件的引用并对其进行管理, 甚至有时会对其生命周期进行管理。
54 public class ConcreteMediator : IMediatorPattern
55 {
56 ConponentA _conponentA;
57 ConponentB _conponentB;
58 ConponentC _conponentC;
59 public ConcreteMediator(ConponentA conponentA, ConponentB conponentB, ConponentC conponentC)
60 {
61 _conponentA = conponentA;
62 _conponentA.SetMediator(this);
63
64 _conponentB = conponentB;
65 _conponentB.SetMediator(this);
66
67 _conponentC = conponentC;
68 _conponentC.SetMediator(this);
69 }
70
71 public void Notify(BaseConponent sender, string param)
72 {
73 if (param.Equals("A"))
74 {
75 Console.WriteLine("A notify C");
76 _conponentC.DoCElse();
77 }
78 else if (param.Equals("B"))
79 {
80 Console.WriteLine("B notify C");
81 _conponentC.DoCElse();
82 }
83 else if (param.Equals("C"))
84 {
85 Console.WriteLine("C notify AB");
86 _conponentA.DoAElse();
87 _conponentB.DoBElse();
88 }
89 }
90 }
91
92
93 //组件 (Component) 是各种包含业务逻辑的类。
94 //每个组件都有一个指向中介者的引用, 该引用被声明为中介者接口类型。
95 //组件不知道中介者实际所属的类, 因此你可通过将其连接到不同的中介者以使其能在其他程序中复用。
96 public abstract class BaseConponent
97 {
98 protected IMediatorPattern _mediator;
99 public BaseConponent(IMediatorPattern mediator = null)
100 {
101 _mediator = mediator;
102 }
103
104 public void SetMediator(IMediatorPattern mediator)
105 {
106 this._mediator = mediator;
107 }
108 }
109
110 //组件并不知道其他组件的情况。 如果组件内发生了重要事件, 它只能通知中介者。
111 //中介者收到通知后能轻易地确定发送者, 这或许已足以判断接下来需要触发的组件了。
112 //对于组件来说, 中介者看上去完全就是一个黑箱。
113 //发送者不知道最终会由谁来处理自己的请求, 接收者也不知道最初是谁发出了请求。
114 public class ConponentA : BaseConponent
115 {
116 public ConponentA(IMediatorPattern mediator = null) : base(mediator)
117 { }
118
119 public void DoA()
120 {
121 Console.WriteLine("A Do something");
122 this._mediator.Notify(this, "A");
123 }
124
125 public void DoAElse()
126 {
127 Console.WriteLine("A Do something else");
128 }
129 }
130
131 public class ConponentB : BaseConponent
132 {
133 public ConponentB(IMediatorPattern mediator = null) : base(mediator)
134 { }
135
136 public void DoB()
137 {
138 Console.WriteLine("B Do something");
139 this._mediator.Notify(this, "B");
140 }
141
142 public void DoBElse()
143 {
144 Console.WriteLine("B Do something else");
145 }
146 }
147
148 public class ConponentC : BaseConponent
149 {
150 public ConponentC(IMediatorPattern mediator = null) : base(mediator)
151 { }
152
153 public void DoC()
154 {
155 Console.WriteLine("C Do something");
156 this._mediator.Notify(this, "C");
157 }
158
159 public void DoCElse()
160 {
161 Console.WriteLine("C Do something else");
162 }
163 }
164
165
166 public class MediatorPatternClient
167 {
168 public static void Test()
169 {
170 ConponentA conponentA = new ConponentA();
171 ConponentB conponentB = new ConponentB();
172 ConponentC conponentC = new ConponentC();
173
174 IMediatorPattern mediator = new ConcreteMediator(conponentA, conponentB, conponentC);
175
176 conponentA.DoA();
177 conponentB.DoB();
178 conponentC.DoC();
179 }
180 }
181 }