这里要讲的是Mediator中介者模式,题目和它有什么关系呢,别急,且慢慢道来。
查阅一下cnblog,很多作者对Mediator模式一般有如下叙述:
a. 中介者模式包装了一系列对象相互作用的方式,使得这些对象不必相互明显作用。从而使他们可以松散偶合。
b. 调停者模式将多对多的相互作用转化为一对多的相互作用
c. 一个对象使用Mediator模式,与其他与其通信的对象解偶, 提高了对象的复用性。
为了说明以上说法的含义和给还不太熟悉这个模式的朋友介绍一下,我们给出类图和代码如下:


C#Code
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}
92
93
看看类图和代码,可不是吗,交互的逻辑在Mediator里,而不在类里面,不就是分离了变化提高了类的复用性吗,本来需要交互而彼此引用许多对象,现在大家只要围着Mediator坐一圈,我只要知道Mediator一个就行了,不就是多对多简化成了一对多?
OK,似乎答案就在这里了,这就是Mediator模式要为我们做的,真的是这样吗?
如果你的理解到此为止的话,我只能说那么你可能永远都不会用到Mediator。不是吗,那我问你,类既然肯定是要和外界交互的,既然一对多肯定要比多对多要好,那么我在定义任何类的时候是不是都应该在其中都定义一个Mediator ? 你见过有人这么做吗 ?
好,如果这个问题引发了你的思考,那么重新审视上面那些关于Mediator适用情况的描述。明白人可能就会问了,“对象之间的交互”这个本来就是另外一个逻辑层才应该关注的事情啊,谁会在设计类的时候把其与周围实体的交互的逻辑一起编写进去呢?这不仅不符合 “单一职责”原则,而且根本上也不可能。既然我们不会这样做,那么就不存在什么“多对多”,既然不存在“多对多”,你哪里来的将“多对多”简化成“一对多”?
如果说什么交互逻辑与类本身解偶,那我说了,用一个Facade模式不是解的更清爽,交互的逻辑都在Facade里,维护一个Facade和维护一个Mediator不是一样?不仅对象之间根本不需要知道彼此,更不需要知道 Mediator!(这样看一个实体还要知道有个Mediator简直是多余嘛)
呵呵,一番思考之后,你会不会嘀咕:Mediator难道是“屠龙之技”?看似华丽优雅,岂知世间本没有龙 !
非也,非也!(当然不会是这样啦,四人帮也不是混饭吃的)强大的Mediator 之所以变成了“屠龙之技”,实在是因为我们误会了它的适用场景而仅仅看它的表面,可以说本文开头的那3条都不是Mediator要解决的问题,而仅仅是我们看了代码后先入为主的想法!
那么Mediator要解决的问题是什么呢? Mediator 与Facade一样都是要在实体间施加策略或者说逻辑,区别在于Facade模式是以明显且受限的方式施加它的策略,而Mediator模式是以隐藏且不受限的方式施加它的策略。
这句话是什么意思呢? 什么叫隐藏方式施加策略? 注意看代码例子的 84 行, 我们把Provider介绍给了Consumer,好了,这是我们唯一看到中介者的地方,以后你还会看到它吗?永远都不会了!(你见过介绍人介绍完对象还一直跟着的吗),以后Provider的变化都会影响通过中介者影响Consumer,但你根本看不到中介者在哪里,它永远静静的呆在幕后,这就是隐藏。
Facade模式下,使用者只会看到Facade,而不会看到隐藏与其下的对象。Mediator 正相反,看的到对象,却看不到Mediator 。但是两者完成的都是在对象间施加某种策略!
Mediator 既不是解决对象之间的耦合问题,也不是解决多对多到一对多,甚至什么增加类的复用之类的问题。
Mediator是用来施加的对象间隐藏并且具有针对性的策略或者说逻辑,这才是它真正要解决的问题。
套用当今流行语,Mediator就是“潜规则”, 表面上看它不存在,作用却是无处不在啊。(做为中国人,更要学好Medaitor了!)
好了,关于Mediator就说这么多了,纠正了它的适用场景,才能真正的在实战中使用。最后要说的就是,学习模式千万不能只看表面,要读懂每个模式背后的故事,那就是它的使用场景,它所要解决的问题,这才是学习模式的关键。