定义:
定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。中介者模式又叫调停模式,它是迪米特法则的典型应用。
模式的结构与实现
中介者模式实现的关键是找出“中介者”,下面对它的结构和实现进行分析。
1. 模式的结构
中介者模式包含以下主要角色。
抽象中介者(Mediator)角色:它是中介者的接口,提供了同事对象注册与转发同事对象信息的抽象方法。
具体中介者(ConcreteMediator)角色:实现中介者接口,定义一个 List 来管理同事对象,协调各个同事角色之间的交互关系,因此它依赖于同事角色。
抽象同事类(Colleague)角色:定义同事类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能。
具体同事类(Concrete Colleague)角色:是抽象同事类的实现者,当需要与其他同事对象交互时,由中介者对象负责后续的交互。
2.模式的实现(以航空调度为例)
假设一个时间段内有三架飞机(川航、深航、国航)准备起飞,也就是说我们有三个对象,只要一架飞机起飞的同时通知其他其他任意一架飞机就好啦,只要在一架飞机的类里放两架其他飞机的引用,很容易就搞定了,当然这样最简单啦。但是这样设计有两个主要缺陷:
1、一旦其中一架飞机比如深航因为目的地天气原因突然停飞,那样我们就要让已经起飞的川航建立国航的连接,这样会很麻烦
2、如果我们又有别的需求,比如又来了另一架飞机(东航),那东航又要关联所有其他航班,更加麻烦
那么我们就引入中介者来弥补缺陷,如下:
抽象同事类(飞机)
public abstract class Plane {
//跑道为闲置状态时,使飞机进入待飞状态
public abstract void readyState(String state);
//飞机起飞
public abstract void flyState(String state, Dispatcher dispatcher);
}
具体同事类1(川航)
public class SCPlane extends Plane {
public void readyState(String state) {
//如果跑道闲置,则调用此方法,待起飞
System.out.println(state + ",请川航好起飞准备");
}
public void flyState(String state, Dispatcher dispatcher) {
//通过传入指令,准备起飞或起飞
System.out.println("川航已离地,"+state);
//通过中介者通知其他飞机使用跑道
dispatcher.SCPlaneFly(state);
}
}
具体同事类2(深航)
public class SZPlane extends Plane {
public void readyState(String state) {
System.out.println(state + ",请深航做好起飞准备");
}
public void flyState(String state, Dispatcher dispatcher) {
System.out.println("深航已离地,"+state);
dispatcher.SZPlaneFly(state);
}
}
具体同事类3(国航)
public class ACPlane extends Plane {
public void readyState(String state) {
System.out.println(state + ",请国航做好起飞准备");
}
public void flyState(String state, Dispatcher dispatcher) {
System.out.println("国航已离地,"+state);
dispatcher.ACPlaneFly(state);
}
}
抽象中介者(航空调度中心)
public abstract class Dispatcher {
//保留所有飞机的引用是为了当接收指令时可以唤醒其他飞机的操作
SCPlane sc;
SZPlane sz;
ACPlane ac;
public Dispatcher(SCPlane sc,SZPlane sz,ACPlane ac){
super();
this.ac = ac;
this.sc = sc;
this.sz = sz;
}
public abstract void SCPlaneFly(String state);
public abstract void SZPlaneFly(String state);
public abstract void ACPlaneFly(String state);
}
具体中介者
public class AirDispatcher extends Dispatcher {
public AirDispatcher(SCPlane sc, SZPlane sz, ACPlane ac) {
super(sc, sz, ac);
}
public void SCPlaneFly(String state) {//川航起飞后,使其他飞机进入待飞状态
sz.readyState(state);//调用深航待飞方法
}
public void SZPlaneFly(String state) {
ac.readyState(state);
}
public void ACPlaneFly(String state) {
sz.readyState(state);
}
}
模拟调度
public class mediatorTest {
public static void main(String[] args) {
SCPlane sc = new SCPlane();
SZPlane sz = new SZPlane();
ACPlane ac = new ACPlane();
AirDispatcher airDispatcher = new AirDispatcher(sc,sz,ac);
sc.flyState("跑道已空出",airDispatcher);
System.out.println("*********fly分割线*********");
sz.flyState("跑道已空出",airDispatcher);
}
}
运行结果
川航已离地,跑道已空出
跑道已空出,请深航做好起飞准备
*********fly分割线*********
深航已离地,跑道已空出
跑道已空出,请国航做好起飞准备
程序分析
1、我们不管是要新增飞机还是替换飞机,既然我们的飞机的关联者只有中介者了,那么修改一下中介者就好了。
2、之前我们是在自己飞机中就能联系其他飞机,现在我们把这种联系统统交给中介者去做。
3、不过可以看出现在的程序变的并不简单,由于我们引入中介者,反而看起来程序变的更加复杂了 。
总结
高内聚,低耦合,使用中介者明显降低了对象之间的耦合
优点
1、通过让对象彼此解耦,增加对象的复用性
2、通过将控制逻辑集中,可以简化系统维护
3、通过中介者使一对所变成了一堆一,便于理解
缺点
1、如果设计不好,引入中介者会使程序变的复杂
2、中介者承担过多责任,维护不好会出大事
实际典型案例
各类消息中间件,比如kafka在系统中担任的角色
转载:https://blog.csdn.net/wsj_xlz/article/details/105300483