兄弟们,老铁们.又到了学习锻炼我们可爱小小大脑的时候了~~~~~ 今天继续来学习设计模式,正所谓一天一个效果不错!! 喝了这碗鸡血,学就完了~~~ 挥霍今天,把眼前的任务许在未来,时间很快就溜走了。我们辜负了时间,时间也会辜负我们的期待。只有珍惜时间的人,才能得到时间的慷慨,一分一秒都有回馈。
1. 调停者模式定义与结构
用一个调停对象来封装一系列的对象交互。调停者使 各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。 简单点来说,将原来两个直接引用或者依赖的对象拆开,在中间加入一个“调停”对象,使得两头的对象分别和“调停”对象引用或者依赖。 组成部分:
- 抽象调停者角色:抽象调停者角色定义统一的接口用于各同事角色之间的通信。
- 具体调停者角色:具体调停者角色通过协调各同事角色实现协作行为。为此它要知道并引用各个同事角色。
- 同事角色:每一个同事角色都知道对应的具体调停者角色,而且与其他的同事角色通信的时候,一定要通过调停者角色协作。

广泛应用的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 手机播放视频
在生活中我们经常使用手机来播放视频,简化并模拟一下过程
- 驱动从存储卡上读取数据流,然后告诉主板它读取到了数据.
- 主板得到数据告诉CPU进行处理.
- CPU处理完后将数据流分成视频和音频数据,再通知主板
- 主板得到视频音频数据后再交给显卡和声卡,显示视频和声音
抽象调停者
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.优缺点
优点:
- 松散耦合:调停者模式通过把多个同事对象之间的交互封装到调停者对象里面,从而使得同事对象之间松散耦合,基本上可以做到互补依赖。这样一来,同事对象就可以独立地变化和复用,而不再像以前那样“牵一处而动全身”了。
- 集中控制交互:多个同事对象的交互,被封装在调停者对象里面集中管理,使得这些交互行为发生变化的时候,只需要修改调停者对象就可以了,当然如果是已经做好的系统,那么就扩展调停者对象,而各个同事类不需要做修改。
- 多对多变成一对多:没有使用调停者模式的时候,同事对象之间的关系通常是多对多的,引入调停者对象以后,调停者对象和同事对象的关系通常变成双向的一对多,这会让对象的关系更容易理解和实现。
缺点:
- 调停者模式的一个潜在缺点是,过度集中化。如果同事对象的交互非常多,而且比较复杂,当这些复杂性全部集中到调停者的时候,会导致调停者对象变得十分复杂,而且难于管理和维护。