前两天介绍了几个不太常用的模式,终于迎来了Mediator。(Mediator 常用吗,也许只是感觉它更像一个模式罢了)
下面到代码结束都是Copy来的,讨论在后面。
调停者模式(中介模式):调停者模式包装了一系列对象相互作用的方式,使得这些对象不必相互明显作用。从而使他们可以松散偶合。当某些对象之间的作用发生改变时,不会立即影响其他的一些对象之间的作用。保证这些作用可以彼此独立的变化。调停者模式将多对多的相互作用转化为一对多的相互作用。调停者模式将对象的行为和协作抽象化,把对象在小尺度的行为上与其他对象的相互作用分开处理。
名称 | Mediator |
结构 | |
意图 | 用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。 |
适用性 |
|
代码:
1// Mediator
2
3// Intent: "Define an object that encapsulates how a set of objects interact.
4// Mediator promotes loose coupling by keeping objects from referring to each
5// other explicitly, and it lets you vary their interaction independently."
6
7// For further information, read "Design Patterns", p273, Gamma et al.,
8// Addison-Wesley, ISBN:0-201-63361-2
9
10/**//* Notes:
11 * Consider a mediator as a hub, which objects that need to talk -
12 * but do not wish to be interdependent - can use.
13 */
14
15namespace Mediator_DesignPattern
16{
17 using System;
18
19 class Mediator
20 {
21 private DataProviderColleague dataProvider;
22 private DataConsumerColleague dataConsumer;
23 public void IntroduceColleagues(DataProviderColleague c1, DataConsumerColleague c2)
24 {
25 dataProvider = c1;
26 dataConsumer = c2;
27 }
28
29 public void DataChanged()
30 {
31 int i = dataProvider.MyData;
32 dataConsumer.NewValue(i);
33 }
34 }
35
36 class DataConsumerColleague
37 {
38 public void NewValue(int i)
39 {
40 Console.WriteLine("New value {0}", i);
41 }
42 }
43
44 class DataProviderColleague
45 {
46 private Mediator mediator;
47 private int iMyData=0;
48 public int MyData
49 {
50 get
51 {
52 return iMyData;
53 }
54 set
55 {
56 iMyData = value;
57 }
58 }
59 public DataProviderColleague(Mediator m)
60 {
61 mediator = m;
62 }
63
64 public void ChangeData()
65 {
66 iMyData = 403;
67
68 // Inform mediator that I have changed the data
69 if (mediator != null)
70 mediator.DataChanged();
71 }
72 }
73
74 /**//// <summary>
75 /// Summary description for Client.
76 /// </summary>
77 public class Client
78 {
79 public static int Main(string[] args)
80 {
81 Mediator m = new Mediator();
82 DataProviderColleague c1 = new DataProviderColleague(m);
83 DataConsumerColleague c2 = new DataConsumerColleague();
84 m.IntroduceColleagues(c1,c2);
85
86 c1.ChangeData();
87
88 return 0;
89 }
90 }
91}
讨论:
表面上来看,Mediator 最明显的是“把对象在小尺度的行为上与其他对象的相互作用分开处理” ,既然把变化的部分分离了,不就是提高了类的复用性嘛,真的是这样吗?
这时候,明白人会看出一些问题,“类的交互”本来就是另一个逻辑层才关注的事情啊,谁会在设计类的时候吧与周围实体的交互的逻辑一起编写进去呢?这也不符合 SRP 啊。既然我们不会这样做,那么就不存在什么“多对多”,既然不存在“多对多”,你用来简化成“一对多”的方法岂不是“屠龙之技”?
所以代码前面那些论述实在是空中楼阁啊。交互再多再复杂我使用一个Facade就行了,犯得着添加一个Mediator到类里面去吗?
呵呵,上面的说法确实是有道理。不过Mediator可不是“屠龙之技”,它自有它的功用。
那就是,Facade模式是以明显且受限的方式施加它的策略,而Mediator是以隐藏且不受限的方式来施加它的策略。注意上面的代码 m.IntroduceColleagues(c1,c2); OK,这一句话就足够了,我们就再也不用注意Mediator的存在了,而它的策略却始终施加在DataProviderColleague上。Mediator 的规则更有针对性。人们不会越过Facade而使用下面的对象,但Mediator对用户却是隐藏的。可以认为Facade是一个看的见的包裹在外面的逻辑层而Mediator是隐藏的逻辑,套用一句是“潜规则”。