bboyjing's blog

HeadFirst设计模式二十一【中介者模式】

使用中介者模式,又叫调停者模式,是用来集中相关对象之间复杂的沟通和控制方式的,使对象之间可以较松散地耦合。比如说WTO组织,各个贸易地区(国家)加入WTO组织之前,贸易状态可能是各个国家之间直接沟通,贸易关系是一张网。WTO是一个协调组织,各个贸易地区可以经由WTO组织进行协调。WTO扮演的正是中介者模式中的中介者角色,它取代了原本由各个贸易地区自行进行的相互协商和谈判的强耦合关系。加入WTO之后,贸易关系都指向了WTO,不再错综复杂。

中介者模式包括一下几种角色:

  • 抽象中介者角色:定义出同事对象到中介者对象的接口,其中主要的方法是一个或多个事件方法。
  • 具体中介者角色:从抽象中介者继承而来,实现了抽象超类所声明的事件方法。具体中介者知晓所有的具体同事类,它从具体同事对象接收消息、向具体同事对象发出命令。可以理解为就是上面说的WTO组织。
  • 抽象同事类角色:定义出中介者到同事对象的接口,同事对象只知道中介者而不知道其余同事对象。
  • 具体同事类角色:所有的具体同事类均从抽象同事类继承而来。每一个具体同事类都很清楚它自己在小范围内的行为,而不知道它在大范围内的目的。可以理解为就是上面说的每一个贸易地区(国家)。

下面我们用一个精简的例子来演示下该模式如何实现。

代码实现

  1. 创建抽象中介者

    1
    2
    3
    4
    5
    6
    public abstract class Mediator {
    /**
    * 事件方法,由子类实现
    */
    public abstract void colleagueChanged(Colleague c);
    }
  2. 创建抽象同事

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    public abstract class Colleague {
    private Mediator mediator;
    /**
    * 获取中介者
    */
    public Mediator getMediator() {
    return mediator;
    }
    public Colleague(Mediator mediator) {
    this.mediator = mediator;
    }
    /**
    * 行为方法,由子类实现
    * 一个同事在得知其他对象有变化时,会执行这个操作
    */
    public abstract void action();
    /**
    * 模拟商业方法,调用此方法可以改变对象的内部状态
    */
    public void change() {
    mediator.colleagueChanged(this);
    }
    }
  3. 实现具体同事类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public class Colleague1 extends Colleague {
    public Colleague1(Mediator mediator) {
    super(mediator);
    }
    @Override
    public void action() {
    System.out.println("This is an action from Colleague1");
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public class Colleague2 extends Colleague {
    public Colleague2(Mediator mediator) {
    super(mediator);
    }
    @Override
    public void action() {
    System.out.println("This is an action from Colleague2");
    }
    }
  4. 创建具体中介者

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    public class ConcreteMediator extends Mediator {
    private Colleague colleague1;
    private Colleague colleague2;
    @Override
    public void colleagueChanged(Colleague c) {
    if (c.getClass().getSimpleName().equals("Colleague1")) {
    colleague2.action();
    } else {
    colleague1.action();
    }
    }
    public void createConcreteMediator() {
    colleague1 = new Colleague1(this);
    colleague2 = new Colleague2(this);
    }
    }
  5. 测试

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public class Test {
    public static void main(String[] args) {
    ConcreteMediator mediator = new ConcreteMediator();
    mediator.createConcreteMediator();
    Colleague colleague1 = new Colleague1(mediator);
    Colleague colleague2 = new Colleague2(mediator);
    mediator.colleagueChanged(colleague1);
    mediator.colleagueChanged(colleague2);
    }
    }

这个模式的重点在于,同事类相互不知道彼此的存在,但是每个对象只和中介者通信;中介者知道每个同事类的存在,从中进行调解。当同事类发生状态改变时,通知中介者,中介者接收到消息再触发响应的命令。上面的实现有一点要注意的是,测试方法中声明的colleague1colleague2ConcreteMediator中的colleague1colleague2不是同一个对象,如果涉及到有状态的交互时,可以将两个地方的对象统一。只要稍加改动即可,这里就不作演示了。本章节就到这里了。