依赖关系的转化
动机(Motivation)
在软件构建过程中,经常会出现多个对象互相关联交互的情况,对象之间常常会维持一种复杂的引用关系,如果遇到一些需求的更改,这种直接的引用关系将面临不断地变化。
在这种情况下,我们可使用一个“中介对象”来管理对象间的关联关系,避免相互交互的对象之间的紧耦合引用关系,从而更好地抵御变化。
意图(Intent)
用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式的相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
——《设计模式》GoF
例说Mediator引用
菜单中的按钮要根据其他的操作来响应它的状态,例如:Undo按钮需要至少进行一次操作才可用;Redo按钮是需要先按下Undo按钮之后才可用等等。
下面的例子讨论剪切操作
每一个对象都和其它三个对象进行关联。这样的关联非常复杂,而且非常脆弱。
这样我们就需要往中介者模式演化,每一个类都引用中介者,由中介者去通知其它对象。
这个时候依赖关系就转化了,我们新添加一个类的时候,互相是不知道的。Element及其子类依赖于抽象的Mediator接口,Mediator也依赖于Element,它们是互相依赖的。但是每一个Element互相是不依赖的。Mediator有改变的时候,需要去找到list一个一个去通知其它Element。
结构(Structure)
Colleague对应Element,ConcreteMediator和ConcreteColleague其实并没有直接依赖,而是间接地依赖。
Mediator模式的几个要点
将多个对象间复杂的关联关系解耦,Mediator模式将多个对象间的控制逻辑进行集中管理,变“多个对象互相关联”为“多个对象和一个中介者关联”,简化了系统的维护,抵御了可能的变化。
随着控制逻辑的复杂化,Mediator具体对象的实现可能相当复杂。这时候可以对Mediator对象进行分解处理。
Facade模式是解耦系统外到系统内(单向)的对相关联关系
Mediator模式是解耦系统内各个对象之间(双向)的关联关系
.NET架构中的Mediator
在WindowsForm中,每一个控件与控件之间都有消息的传递。
在WindowsForm中的ApplicationContext类扮演了一个中介者的角色,它走了整个的消息循环,把所有进来的消息进行处理。
在每个控件里面都有个WndProc方法的重载,它其实就是处理每个消息的方法
WindowsForm里面的控件都继承自Control类,Control类就是上面例子中的Element类,而WndProc方法就是上面例子中的OnChange方法。
这个方法负责处理所有的消息,它里面也体现了复杂度,它里面做了很多的Switch来判断是什么样的消息。当点击一个Button,其它控件就通过ApplicationContext来进行反应。