java中23种设计模式--调停者模式

448 阅读5分钟

兄弟们,老铁们.又到了学习锻炼我们可爱小小大脑的时候了~~~~~ 今天继续来学习设计模式,正所谓一天一个效果不错!! 喝了这碗鸡血,学就完了~~~ 挥霍今天,把眼前的任务许在未来,时间很快就溜走了。我们辜负了时间,时间也会辜负我们的期待。只有珍惜时间的人,才能得到时间的慷慨,一分一秒都有回馈。

1. 调停者模式定义与结构

用一个调停对象来封装一系列的对象交互。调停者使 各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。 简单点来说,将原来两个直接引用或者依赖的对象拆开,在中间加入一个“调停”对象,使得两头的对象分别和“调停”对象引用或者依赖。 组成部分:

  1. 抽象调停者角色:抽象调停者角色定义统一的接口用于各同事角色之间的通信。
  2. 具体调停者角色:具体调停者角色通过协调各同事角色实现协作行为。为此它要知道并引用各个同事角色。
  3. 同事角色:每一个同事角色都知道对应的具体调停者角色,而且与其他的同事角色通信的时候,一定要通过调停者角色协作。 在这里插入图片描述

广泛应用的MVC中的控制层可以理解为表现层和模型层之间的调停者.由于调停者模式在定义上比较松散,在结构上与观察者模式,命令模式十分相似.

2. 调停者模式实现

先举一个最简单的例子 抽象调停者

//抽象调停者
public interface Mediator {

  public void changed(Colleague colleague);

}

具体调停者

//具体调停者
public class ConcreteMediator implements Mediator{

  //具体同事
  private ColleagueA colleagueA;

  private ColleagueB colleagueB;

  public void setColleagueA(ColleagueA colleagueA) {
    this.colleagueA = colleagueA;
  }

  public void setColleagueB(ColleagueB colleagueB) {
    this.colleagueB = colleagueB;
  }

  @Override
  public void changed(Colleague colleague) {
    //当某个同事发生变化时通知其他同事进行交互
  }
}

抽象同事

//抽象同事类
public abstract class Colleague {

  //调停者
  private Mediator mediator;

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

  public Mediator getMediator(){
    return mediator;
  }

}

同事 A

public class ColleagueA extends Colleague {

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

  public void doSome(){
    getMediator().changed(this);
  }
}

同事 B

public class ColleagueB extends Colleague {

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

  public void doSome(){
    getMediator().changed(this);
  }
}

2.1 手机播放视频

在生活中我们经常使用手机来播放视频,简化并模拟一下过程

  1. 驱动从存储卡上读取数据流,然后告诉主板它读取到了数据.
  2. 主板得到数据告诉CPU进行处理.
  3. CPU处理完后将数据流分成视频和音频数据,再通知主板
  4. 主板得到视频音频数据后再交给显卡和声卡,显示视频和声音

抽象调停者

public interface Mediator {

  public void changed(Colleague colleague);

}

具体调停者 在这里主板就相当于调停者

//具体调停者
public class Motherboard implements Mediator{

  //具体同事-CPU
  private CPU cpu;
  //具体同事-显卡
  private GraphicsCard graphicsCard;
  //具体同事-声卡
  private SoundCard soundCard;
  //具体同事-驱动
  private Drive drive;

  public void setCpu(CPU cpu) {
    this.cpu = cpu;
  }

  public void setGraphicsCard(GraphicsCard graphicsCard) {
    this.graphicsCard = graphicsCard;
  }

  public void setSoundCard(SoundCard soundCard) {
    this.soundCard = soundCard;
  }

  public void setDrive(Drive drive) {
    this.drive = drive;
  }

  @Override
  public void changed(Colleague colleague) {
    if (colleague instanceof Drive){
      this.doDrive((Drive) colleague);
    }else if (colleague instanceof CPU){
      this.doCPU((CPU) colleague);
    }
  }

  private void doCPU(CPU cpu) {
    //获取数据
    String video = cpu.getVideo();
    String sound = cpu.getSound();

    graphicsCard.video(video);
    soundCard.sound(sound);
  }

  private void doDrive(Drive drive) {
    //cpu解析数据
    cpu.resolve(drive.getStreamData());
  }
}

抽象同事类

//抽象同事类
public abstract class Colleague {

  //调停者
  private Mediator mediator;

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

  //获取同事对应的调停者
  public Mediator getMediator() {
    return mediator;
  }
}

同事类 - 驱动

//同事-驱动
public class Drive extends Colleague {

  private String streamData = "";

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

  public String getStreamData() {
    return streamData;
  }

  public void readData(){
    streamData = "the first price,今天来学习调停者模式";
    //通知主板
    getMediator().changed(this);
  }
}

同事类 - CPU

//同事-CPU
public class CPU extends Colleague {

  //视频数据
  private String video = "";

  //声音数据
  private String sound = "";

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

  public String getVideo() {
    return video;
  }

  public String getSound() {
    return sound;
  }

  //解析数据
  public void resolve(String streamData){
    String[] split = streamData.split(",");
    this.video = split[0];
    this.sound = split[1];
    getMediator().changed(this);
  }
}

同事类 - 显卡

public class GraphicsCard extends Colleague {

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

  //显示
  public void video(String video){
    System.out.println("开始播放 : " + video);
  }
}

同事类 - 声卡

public class SoundCard extends Colleague {

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

  //播放
  public void sound(String sound){
    System.out.println("----视频声音---- : " + sound);
  }
}

测试

 public static void main(String[] args) {
    //主板 调停者
    Motherboard motherboard = new Motherboard();
    //同事
    Drive drive = new Drive(motherboard);
    CPU cpu = new CPU(motherboard);
    GraphicsCard graphicsCard = new GraphicsCard(motherboard);
    SoundCard soundCard = new SoundCard(motherboard);

    motherboard.setCpu(cpu);
    motherboard.setDrive(drive);
    motherboard.setGraphicsCard(graphicsCard);
    motherboard.setSoundCard(soundCard);

    drive.readData();
  }

运行后就可以看到结构

开始播放 : the first price
----视频声音---- : 今天来学习调停者模式

3.优缺点

优点:

  • 松散耦合:调停者模式通过把多个同事对象之间的交互封装到调停者对象里面,从而使得同事对象之间松散耦合,基本上可以做到互补依赖。这样一来,同事对象就可以独立地变化和复用,而不再像以前那样“牵一处而动全身”了。
  • 集中控制交互:多个同事对象的交互,被封装在调停者对象里面集中管理,使得这些交互行为发生变化的时候,只需要修改调停者对象就可以了,当然如果是已经做好的系统,那么就扩展调停者对象,而各个同事类不需要做修改。
  • 多对多变成一对多:没有使用调停者模式的时候,同事对象之间的关系通常是多对多的,引入调停者对象以后,调停者对象和同事对象的关系通常变成双向的一对多,这会让对象的关系更容易理解和实现。

缺点:

  • 调停者模式的一个潜在缺点是,过度集中化。如果同事对象的交互非常多,而且比较复杂,当这些复杂性全部集中到调停者的时候,会导致调停者对象变得十分复杂,而且难于管理和维护。