中介者模式(Mediator)
定义
Define an object that encapsulates how a set of objectsinteract.Mediator promotes loose coupling by keeping objects from referring to each otherexplicitly,and it lets you vary their interaction independently
(定义一个中介对象封装一系列其他对象,中介使对象不必显示地相互调用,从而使其松散耦合,而且可以独立地改变它们之间的交互)
说明
在介绍中介者模式前先看两张图,途中的A-J代表系统中的对象,连线代表调用关系。
不使用中介者模式时对象间的关系图:
图一是在不启用中介者模式时的对象调用关系图,其复杂程度也许不止图中所表示的调用关系,在极端情况下可能会出现(n-1)+ ( n − 1 ) 2 (n-1)^{2} (n−1)2种可能,通过公式可发现调用个数随着对象的增多将以指数的形式激增,如果系统种有几百个对象并且它们之间都要通信,那么这样的系统是无法维护的。
图二中引入一个中介类,所有的对象都不再直接通信,而是通过中介者类统一分发,对象不必关心中介者类的实现细节,只需要根据需求直接调用接口即可,这样的调用数量最大n。调用从指数量级降到了线性量级,极大降低了系统复杂度。
在面向对象的设计中鼓励开发者将行为分散到各个对象中,但是这种分布不仅会照成对象的剧增还会导致对象间有许多调用,在最坏的情况下几乎每个对象都要知道其他对象。也许这样的系统人们认为会具有优秀的模块复用性,但实际情况是由于每个对象与其他对象都有千丝万缕的联系,不仅不易于复用,反而由于调用频繁结构复杂而照成系统的可读性差,导致复用性大大降低(都都读不通何谈复用)。
大量的互相调用相互连接使得一个对象不大可能单独完成一项工作,模块间耦合性高,模块内内聚性低,整个系统变成一个不可分隔的整体,因为行为被分散在许多对象中,删也删不得、改又改不动。
中介者模式是为了把复杂的逻辑简单化,是项目发展到一定规模时弱化项目复杂度的手段。中介者模式又名调停模式,调停的是类间的复杂调用,当类间的调用比较清晰时没必要使用中介者模式。如果类间的调用非常非常复杂是不是就可以使用中介者了那?答案也是否定的,如果接口调用太复杂也会导致中介类的复杂,中介类的复杂性会随着业务的复杂度上升,而逻辑的复杂性会让中介类难以维护,因此开发中还是要认真梳理业务,前期设计一定要做好,单靠一两个技术点是无法解决所有问题的。
中介者类图:
所有的成员都要知道Mediator,类图中可以看出ConcreteColleague1和ConcreteColleague2之间的调用要统一通过Mediator,并且在Mediator的实现类中要实现所有需要交互的方法,而发生调用的对象本身不再发生相互依赖关系。
结构
中介者模式中的角色
Mediator 抽象中介者:抽象中介者角色定义接口,用于各同事Colleague之间的通信
ConcreteMediator 具体中介者:
具体中介者实现抽象中介者接口,用于协调各同事之间的调用关系,因此具体中介者要依赖所有它要协调行为的同时
Colleague 同事角色:
同事角色往往是那些与它们的同事通信频繁的对象,同事角色要知道具体中介者,并通过调用中介者方法间接的实现与同事之间的通信行为。
中介者模式的优势
1、 中介者模式的最大作用就是减少了类间依赖,降低了类间耦合,所有的类只依赖中介者对象,有原来的一对多关系将为一对一,一对一的关系无疑是更容易维护和扩展的。
2、由于所有的访问都要经过中介者,从而使控制集中化,有利于接口限制及赋能。
3、中介类规模适当的情况下更容易从宏观角度参看系统功能,有利于开发中复用已有接口。
中介者模式的使用
1、j2ee中的mvc框架中的C(Controller)就是一个中介者,其功能是将M(Model)模型与V(View)视图分开,协调M和V的工作,减少M和V的依赖关系。
2、网关、路由都是中介者,我们把消息发送给网关,网关帮我们把消息转出去。路由器转发收到的报文。