Don't think you are, know you are

博客园 首页 新随笔 管理


前两天介绍了几个不太常用的模式,终于迎来了Mediator。(Mediator 常用吗,也许只是感觉它更像一个模式罢了)

下面到代码结束都是Copy来的,讨论在后面。

调停者模式(中介模式):调停者模式包装了一系列对象相互作用的方式,使得这些对象不必相互明显作用。从而使他们可以松散偶合。当某些对象之间的作用发生改变时,不会立即影响其他的一些对象之间的作用。保证这些作用可以彼此独立的变化。调停者模式将多对多的相互作用转化为一对多的相互作用。调停者模式将对象的行为和协作抽象化,把对象在小尺度的行为上与其他对象的相互作用分开处理。

名称 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}

讨论:

表面上来看,Mediator 最明显的是“把对象在小尺度的行为上与其他对象的相互作用分开处理” ,既然把变化的部分分离了,不就是提高了类的复用性嘛,真的是这样吗?

这时候,明白人会看出一些问题,“类的交互”本来就是另一个逻辑层才关注的事情啊,谁会在设计类的时候吧与周围实体的交互的逻辑一起编写进去呢?这也不符合 SRP 啊。既然我们不会这样做,那么就不存在什么“多对多”,既然不存在“多对多”,你用来简化成“一对多”的方法岂不是“屠龙之技”?

所以代码前面那些论述实在是空中楼阁啊。交互再多再复杂我使用一个Facade就行了,犯得着添加一个Mediator到类里面去吗?

呵呵,上面的说法确实是有道理。不过Mediator可不是“屠龙之技”,它自有它的功用。

那就是,Facade模式是以明显且受限的方式施加它的策略,而Mediator是以隐藏且不受限的方式来施加它的策略。注意上面的代码  m.IntroduceColleagues(c1,c2); OK,这一句话就足够了,我们就再也不用注意Mediator的存在了,而它的策略却始终施加在DataProviderColleague上。Mediator 的规则更有针对性。人们不会越过Facade而使用下面的对象,但Mediator对用户却是隐藏的。可以认为Facade是一个看的见的包裹在外面的逻辑层而Mediator是隐藏的逻辑,套用一句是“潜规则”。



 

posted on 2007-08-03 17:24  炭炭  阅读(534)  评论(0编辑  收藏  举报