四 行为型-中介者模式

185 阅读3分钟

本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。
小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

image.png 其他设计模式介绍
创建型: 工厂方法 抽象工厂 原型
结构型: 适配器 桥接模式 组合模式 装饰模式 外观模式 享元模式 代理模式
行为型: 职责链 命令 解释器 迭代器 中介者 备忘录 状态模式 策略模式 模板方法 访问者

定义

中介这个词并不陌生,就是房屋中介的那个“中介”,就是中间人的意思。比如MVC模式,C(Controller控制器)是M(Model模型)和V(View视图)的中介者,在前后端交互时起到了中间人的作用。
用一个中介对象来封装一系列的对象交互。中介者使各个对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互

1.UML

image.png 其中,Mediator是抽象中介者,定义了同事对象到中介者对象的接口;Colleague是抽象同事类;ConcreteMediator是具体中介者对象,实现抽象类的方法,它需要知道所有具体同事类,并从具体同事接收消息,向具体同事对象发出命令;ConcreteColleague是具体同事类,每个具体同事只知道自己的行为,而不了解其它同事类的情况,但它们却都认识中介者对象。

2.抽象中介者

  抽象中介者角色定义统一的接口,用于各同事角色之间的通信。

public abstract class Mediator {

  //抽象的发送消息方法
  public abstract void send(String message, Colleague colleague);

}

3.抽象同事类

  每一个同事角色都知道中介者角色,而且与其它的同事角色通信的时候,一定要通过中介者角色协作。每个同事类的行为分两种:一种是同事本身行为,比如改变对象本身的状态,处理自己的行为等,这种行为叫做自发行为,与其它同事类或者中介者没有任何依赖;第二种是必须依赖中介者才能完成的行为,叫做依赖方法。

public abstract class Colleague {

  protected Mediator mediator;

  public Colleague(Mediator mediator) {
      this.mediator = mediator;
  }

}

4.具体中介者类

  具体中介者角色通过协调各同事角色实现协作行为,因此它必须依赖于各个同事角色。

public class ConcreteMediator extends Mediator {

  private ConcreteColleague1 colleague1;
  private ConcreteColleague2 colleague2;

  public void setColleague1(ConcreteColleague1 colleague1) {
      this.colleague1 = colleague1;
  }

  public void setColleague2(ConcreteColleague2 colleague2) {
      this.colleague2 = colleague2;
  }

  @Override
  public void send(String message, Colleague colleague) {
      if(colleague == colleague1) {
          colleague2.notify(message);
      } else {
          colleague1.notify(message);
      }
  }

}

5.具体同事类

  这里以ConcreteColleague1为例,ConcreteColleague2不再赘述。

public class ConcreteColleague1 extends Colleague {

  public ConcreteColleague1(Mediator mediator) {
      super(mediator);
  }

  public void send(String message) {
      mediator.send(message, this);
  }

  public void notify(String message) {
      System.out.println("同事1得到消息:" + message);
  }

}

6.Client客户端

  首先创建一个具体中介者对象,然后实例化两个具体同事类并与该中介者进行绑定,colleague1与colleague2通过中介者发送信息。

public class Client {

  public static void main(String[] args) {
      ConcreteMediator mediator = new ConcreteMediator();

      ConcreteColleague1 colleague1 = new ConcreteColleague1(mediator);
      ConcreteColleague2 colleague2 = new ConcreteColleague2(mediator);

      mediator.setColleague1(colleague1);
      mediator.setColleague2(colleague2);

      colleague1.send("Nice to meet u.");
      colleague2.send("Nice to meet u too.");
  }

}

image.png

中介者模式的应用

何时使用

  • 多个类相互耦合,形成网状结构时

方法

  • 将网状结构分离为星型结构

优点

  • 减少类间依赖,降低了耦合
  • 符合迪米特原则

缺点

  • 中介者会膨胀的很大,而且逻辑复杂

使用场景

  • 系统中对象之间存在比较复杂的引用关系
  • 想通过一个中间类来封装多个类的行为,而又不想生成太多的子类

应用实例

  • 联合国/WTO作为中介者协调各个国家
  • 房屋中介/机场调度系统
  • MVC框架,其中C(Contorller控制器)是M(Model模型)和V(View视图)的中介者

注意事项

  • 不应当在职责混乱时使用