写点什么

【设计模式系列 17】中介者模式原理及其在 JDK 源码中的体现

  • 2021 年 11 月 11 日
  • 本文字数:2706 字

    阅读完需:约 9 分钟

前言


===============================================================


本文主要介绍中介者模式的原理,并会结合示例进行分析。中介者模式其实和桥接有点相似,桥接模式也是通过组合来实现的,但是中介者模式和桥接模式的侧重点不一样,接下来就让我们一起来看看中介者模式吧。


什么是中介者模式


=====================================================================


中介者模式(Mediator Pattern)又称为调节者模式或者调停者模式,是用来降低多个对象和类之间的通信复杂性。


中介者模式中用一个中介对象封装一系列的对象交互,从而使各个对象不需要显示的相互作用,达到松耦合的目的,使得维护更加容易。当某些对象之间的作用发生改变时,不会立刻影响其他的一些对象之间的作用,保证了对象之间的相互作用可以独立的变化。


中介者模式属于行为型模式,其核心思想是通过中介者对象解耦各层次对象的直接耦合,层次对象的对外依赖通信全部交由中介者转发。


为什么需要中介者模式


=======================================================================


假如现在有六个对象,对象与对象之间都需要互相调用,那么它们的关系就会如下图所示:



各个对象之间互相依赖,整个依赖关系形成了网状,关系错综复杂,非常难以管理。这时候如果引入一个中介者,每个对象都只和中介者交互,那么它们之间的关系就会如下图所示:



可以看到,所有的对象之间的关系都归中介者进行统一管理,避免了各个对象之间各自依赖的乱像。


其实在生活中也一样,比如飞机航线,假如有多驾飞机都需要走同一条航线,那么到底什么时候能走,谁先走就会是一个问题,如果各架飞机之间自己去协商,那么会非常复杂而且容易出错,所以这时候就需要有塔台来统一调度,而塔台扮演的角色就是中介者对象。


中介者模式示例


====================================================================


好了,装逼时刻又到了:Talk is cheap,Show you the code,先看一个非常简单的例子。


我们就以上面的航空塔台为例子来写一个示例:


1、首先建立一个抽象的 Plane 类,当然这里其实可以不用抽象类,为了方便功能扩展一般我们都是建议面向抽象编程:


package com.lonely.wolf.note.design.pattern.mediator;


public abstract class AbstractPlane {


protected AbstractMediator mediator;


public AbstractPlane(AbstractMediator mediator) {


this.mediator = mediator;


}


public abstract void fly();


}


注意这里面持有了一个抽象中介者对象的引用,稍后我们就会建立中介者对象


2、然后新建两个具体的 PlaneAPlaneB 来继承抽象服务类:


package com.lonely.wolf.note.design.pattern.mediator;


public class PlaneA extends AbstractPlane {


public PlaneA(AbstractMediator mediator) {


super(mediator);


}


@Override


public void fly() {


System.out.println("我是 PlaneA,要过航线,请让道");


super.mediator.notifyPlaneB();


}


public void notifyMe(){


System.out.println("我是 PlaneA,已收到通知,准备让道");


}


}


package com.lonely.wolf.note.design.pattern.mediator;


public class PlaneB extends AbstractPlane {


public PlaneB(AbstractMediator mediator) {


super(mediator);


}


@Override


public void fly() {


System.out.println("我是 PlaneB,要过航线,请让道");


super.mediator.notifyPlaneA();


}


public void notifyMe(){


System.out.println("我是 PlaneB,已收到通知,准备让道");


}


}


注意上面这两个类,重写的抽象方法 fly() 会依赖另一个服务,另外各自有一个接收对方服务的方法 notifyMe(),如果说我们不使用中介者对象来实现,那么 A 就必须要持有 B,而 B 又要持有 A,服务一多,调用关系就会呈现上面的网状形式。而如果有了中介者对象就不一样了,这些服务就可以全部交由中介者来统一管理。


3、建立一个抽象中介者对象:


package com.lonely.wolf.note.design.pattern.mediator;


public abstract class AbstractMediator {


protected Pl


【一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


aneA planeA;


protected PlaneB planeB;


public void setPlaneA(PlaneA planeA) {


this.planeA = planeA;


}


public void setPlaneB(PlaneB planeB) {


this.planeB = planeB;


}


public abstract void notifyPlaneA();


public abstract void notifyPlaneB();


}


4、再建立一个具体的中介者对象塔台:


package com.lonely.wolf.note.design.pattern.mediator;


public class ControlTower extends AbstractMediator{


@Override


public void notifyPlaneA() {


super.planeA.notifyMe();


}


@Override


public void notifyPlaneB() {


super.planeB.notifyMe();


}


}


5、最后我们建立一个测试类来测试一下:


package com.lonely.wolf.note.design.pattern.mediator;


public class TestMediator {


public static void main(String[] args) {


AbstractMediator controlTower = new ControlTower();


PlaneA planeA = new PlaneA(controlTower);


PlaneB planeB = new PlaneB(controlTower);


controlTower.setPlaneA(planeA);


controlTower.setPlaneB(planeB);


planeA.fly();


System.out.println("--------------------");


planeB.fly();


}


}


输出结果如下:


我是 PlaneA,要过航线,请让道


我是 PlaneB,已收到通知,准备让道




我是 PlaneB,要过航线,请让道


我是 PlaneA,已收到通知,准备让道


可以看到,在这个例子中我们实现了 PlaneAPlaneB 的互相调用,但是相互都不持有对方的引用,而是通过一个中介者对象来统一管理,如果后续需要新增其他服务的调用,那么只需要改变中介者对象就可以了。


中介者模式角色


====================================================================


从上面示例中,我们可以得出中介者模式主要有 4 个角色:


  • 抽象中介者(Mediator):定义一个抽象角色,用于各个同事角色之间的通信(如示例中的 AbstractMediator)。

  • 具体中介者(ConcreteMediator):从具体同事的对象接收消息,并像具体同事对象发出命令,用来协调各个同事对象之间通信协作(如示例中的 ControlTower)。

  • 抽象同事类(Colleague):每一个同事对象均需要依赖中介者角色,所以一般将中介者角色集成到该角色之中,与其他同事在通信时,通过中介者角色进行转发(如示例中的 AbstractPlane)。

  • 具体同事类(ConcreteColleague):负责实现自发行为(Self-Method),转发依赖方法(Dep-Method)交由中介者进行协调处理(如示例中的 PlaneAPlaneB,自发行为就是方法 notifyMe() 方法,转发行为对应 fly() 方法)。


中介者模式和桥接模式的区别


==========================================================================

评论

发布
暂无评论
【设计模式系列17】中介者模式原理及其在JDK源码中的体现