问题:
不同对象间需要知道其他对象的。
将一个系统分隔成许多对象通常可以增加其可复用性,但是对象间相互连接的激增又会降低其可复用性。
大量的连接使得一个对象不可能在没有其他对象的支持下工作,系统表现为一个不可分隔的整体。所以,对系统的行为进行任何较大的改动就十分困难了。
解决:
通过中介对象,可以将系统的网状结构变成以中介者为中心的星形结构。
每个具体对象不再通过直接的联系与另一个对象发生相互作用,而是通过“中介者”对象与另一个对象发生相互作用。
中介者对象的设计,使得系统的结构不会因为新对象的引入造成大量的修改工作。
例如,.NET的windows应用程序中的Form或web网站应用程序的aspx(控件之间的通信,都是通过form窗体代码完成),form窗体就是中介,操作各个对象。
定义:
用一个中介对象来封装一系列的对象交互。
中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
优点:
Mediator的出现减少了各个Colleague的耦合,使得可以独立地改变、复用各个Colleague类、Mediator。(任何国家的改变不会影响到其他国家,而只是与安理会发生变化)。
把对象间如何协作进行了抽象,将终结作为一个独立的概念并将其封装在一个对象中,这样关注的对象就从对象各自本身的行为转义到它们之间的交互上来。即,站在一个更宏观的角度去看待系统。(对象间行为,狭隘;中介者,更加全面,宏观)
缺点:
具体中介者类ConcreteMediator可能会因为ConcreteColleague越来越多,而变得非常复杂,反而不容易维护了。
即,ConcreteMediator控制的集中化,交互复杂性变为了中介者的复杂性,使得中介者会变得比任何一个ConcreteColleague都复杂。
中介者模式的优点来自于集中控制,缺点也是它,使用前需考虑清楚。(关键在于,ConcreteMediator,必须要知道所有的ConcreteColleague。减少了ConcreteColleague类之间的耦合,但是使得ConcreteMediator责任过多,如果它除了问题,整个系统都会有问题了。)
注意:
中介者模式很容易在系统中应用,也很容易在系统中误用。
当系统中出现了“多对多”交互负载的对象群时,不要急于使用中介者模式,而要先反思你的系统在设计上是不是合理。
应用:
1.一组对象(以定义良好但是复杂的方式)进行通信的场合。
2.想定制一个分布在多个类中的行为,而不想生成太多的子类的场合。
结构图:
Mediator
Colleague
ConcreteMediator
ConcreteColleague,只知道自己的行为,不了解其他同事类的情况。但它们却都认识中介者对象。
客户端:
ConcreteColleague间发送、接收消息,其实是通过中介者来完成的,减少了它们间的耦合度。
注意:
如果不存在扩展的情况,Mediator可以与ConcreteMediator合二为一。
联合国包括案例为、国际劳工组织、教科文组织……,因此Mediator、ConcreteMediator需分开写。
示例:
客户端:
结果:
扩展:
迪米特法则:
如果两个类不必直接通信,那么这两个类就不应当发生直接的相互作用。
如果其中一个类需要调用另一个类的某一方法的话,可以通过这个第三者转发这个调用。