中介者模式(Mediator)
调度、调停
如上图所示,虽然系统对外呈现是一个统一的整体,但是,内部各个模块之间很可能是紧密的耦合
各个模块相互联系,可能互相持有引用,会出现网状结构,完全不符合迪米特法则。
如果对系统进行改动,将会变得困难。
我们以装修为例
一般装修公司都会给每一个项目配备一个项目经理(这个项目也就是你家这个单子了,项目经理就是包工头)
装修的一般阶段分为:前期设计→拆改→水电→瓦工→木工→油漆→安装→保洁→软装
项目经理手上经常同时有几个工地在同步进行,只要错的开就好了
因为每个阶段都是有先后顺序的,你不可能先木工,然后再去拆改;
因为每个阶段也都需要一定时间,也意味着这一拨人不可能同时在你家工作
开工后项目经理会进行工作安排
水电工结束了A之后,项目经理会安排他到B,然后安排瓦工到A,然后........
所有的顺序都是由项目经理负责调度,水电工可以完全不认识瓦工,他们也完全不需要进行联系
有事儿找项目经理
如果没有项目经理,会是什么场景?
那就是人人都是项目经理,人人都需要管自己,还需要管别人
也就是每个人安排分配自己的时间与任务
水电工结束后需要联系瓦工进场,如果瓦工发现有遗留问题,需要联系水电工进行沟通
木工需要联系瓦工确认进展情况,油漆工又需要确认木工状况...
你会发现他们必须要经常保持联系,以获得进展情况,进而安排自己的工作
一个包工队尚且如此,如果是一个大的装修公司,怎么办?
而且装修而言,阶段之间还会有顺序,油漆工用不到联系水电工
但是在系统中,对象岂会仅仅与一个对象联系?
那岂不是更复杂、乱套?
中介者模式就是为了解决系统内部的调度问题,降低系统内部各模块之间的耦合度。
装修公司的项目经理、小组组长、班长,团队leader等其实这都是中介者模式的体现。
有很多书中以“房屋中介”作为中介者模式的一种场景
个人认为对于某一个房东或者租客而言,“房屋中介”的含义是为你服务的中介人员,此时的含义更接近代理模式
而从广义上看,有很多租客、买家,也存在很多房东,“房屋中介”将他们联系在一起,此时的“房租中介”应该是中介公司,这时才更符合中介者模式的含义
中介者模式的重点在于“调度、协调”,含义更接近“指挥中心”,被指挥的是该系统内部的成员
如果在一个系统中对象之间存在多对多的相互关系
我们可以将对象之间的一些交互行为从各个对象中分离出来,并集中封装在一个中介者对象中,并由该中介者进行统一协调
如上图所示,对象之间多对多的复杂关系就转化为相对简单的一对多关系
简化了对象之间的复杂交互
显然,中介者模式是迪米特法则(不要和陌生人说话)的典型。
结构
同事角色Colleague
系统中所有组成部件的抽象角色
具体的同事角色ConcreteColleague
系统的每一个具体的组成部分,就像公司的每个同事
提供自身职责功能的方法接口,供中介者调用
定义中介者到同事对象的接口,也就是提供接口给中介者调用
中介者(项目经理)根据你的技能分配任务,也就是调用你的方法
中介者角色Mediator
定义了同事Colleague对象到中介者的接口,也就是所有同事通信的接口(同事间的通信借助于中介者提供的这个方法)
也就是提供一个方法给同事们调用,用来请求其他同事协助协助,这个方法是中介者提供的
这个方法典型的示例就是事件处理方法
具体的中介者ConcreteMediator
具体的中介者,实现Mediator定义的接口,协调各同事进行协作
所有的成员之间,可以相互协调工作,但是却又不直接相互管理
这些对象都与项目经理“中介者”进行紧密联系
由项目经理进行工作协调,每个组成部分就如同我们项目组中的一个成员,也就是同事一样,这也是上文中Colleague 角色的由来
如何相互协调工作但是却又不直接相互管理?比如
class A{ void f(){ //do sth B b = new B(); b.g(); }





