调停者模式的意图是定义个对象,封装一组对象的交互,从而降低对象间的耦合度,避免了对象间显示的引用,并且可以独立的改变对象的行为。
过度耦合系统引入调停者
如果电脑没有主板
下面来看看调停者模式的UML类图:
代码实例
抽象同事类
public abstract class Colleague {
private Mediator mediator;
public Colleague(Mediator mediator) {
this.mediator = mediator;
}
public Mediator getMediator() {
return mediator;
}
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
}
抽象调停者
public interface Mediator {
/**
* 同事对象在自身改变的时候来通知调停者方法,让调停者负责相应的与其他同事的交互
* @author 付玉伟
* @time 2015-2-12 下午10:11:35
* @param c
*/
public void changed(Colleague c);
}
同事类
public class CdDriver extends Colleague {
/**
* 光驱读取的数据
*/
private String data = "";
public CdDriver(Mediator mediator) {
super(mediator);
}
/**
* 获取光驱读取出来的数据
* @author 付玉伟
* @time 2015-2-12 下午10:16:59
* @return
*/
public String getData() {
return data;
}
/**
* 读取光盘
* @author 付玉伟
* @time 2015-2-12 下午10:17:27
*/
public void readCD(){
this.data = "《变形金刚4》,我要变身了";
// 通知主板,已经读取到光盘信息
getMediator().changed(this);
}
public void setData(String data) {
this.data = data;
}
}
public class Cpu extends Colleague {
/**
* 分解出来的视频数据
*/
private String videoData = "";
/**
* 分解出来的声音数据
*/
private String soundData = "";
public Cpu(Mediator mediator) {
super(mediator);
}
/**
* 获取分解出来的视频数据
* @author 付玉伟
* @time 2015-2-12 下午10:22:52
* @return
*/
public String getVideoData() {
return videoData;
}
public void setVideoData(String videoData) {
this.videoData = videoData;
}
/**
* 获取分解出来的音频数据
* @author 付玉伟
* @time 2015-2-12 下午10:23:03
* @return
*/
public String getSoundData() {
return soundData;
}
public void setSoundData(String soundData) {
this.soundData = soundData;
}
/**
* 处理数据,把数据分为音频和视频
* @author 付玉伟
* @time 2015-2-12 下午10:23:59
* @param data
*/
public void executeData(String data){
String[] array = data.split(",");
this.videoData = array[0];
this.soundData = array[1];
// 通知主板,CPU完成工作
getMediator().changed(this);
}
}
public class SoundCard extends Colleague {
public SoundCard(Mediator mediator) {
super(mediator);
}
public void soundData(String data){
System.out.println("画外音:"+data);
}
}
具体调停者
public class MainBoard implements Mediator {
private CdDriver cdDriver;
private Cpu cpu;
private SoundCard soundCard;
private VideoCard videoCard;
public void changed(Colleague c) {
if(c instanceof CdDriver){
// 表示光驱读取数据了
this.operCdDriverReadData((CdDriver)c);
}else if(c instanceof Cpu){
this.operCpu((Cpu)c);
}
}
/**
* 处理读取光驱数据后与其他对象的交互
* @author 付玉伟
* @time 2015-2-12 下午10:33:42
* @param cd
*/
public void operCdDriverReadData(CdDriver cd){
// 先获取光驱读取的数据
String data = cd.getData();
// 把这些数据传给CPU处理
cpu.executeData(data);
}
/**
* 处理cpu处理完的数据后与其他对象的交互
* @author 付玉伟
* @time 2015-2-12 下午10:33:35
* @param cpu
*/
public void operCpu(Cpu cpu){
// 先获取CPU处理后的数据
String videoData =cpu.getVideoData();
String soundData = cpu.getSoundData();
// 把这些数据传给声卡、显卡展示出来
videoCard.showData(videoData);
soundCard.soundData(soundData);
}
public CdDriver getCdDriver() {
return cdDriver;
}
public void setCdDriver(CdDriver cdDriver) {
this.cdDriver = cdDriver;
}
public Cpu getCpu() {
return cpu;
}
public void setCpu(Cpu cpu) {
this.cpu = cpu;
}
public SoundCard getSoundCard() {
return soundCard;
}
public void setSoundCard(SoundCard soundCard) {
this.soundCard = soundCard;
}
public VideoCard getVideoCard() {
return videoCard;
}
public void setVideoCard(VideoCard videoCard) {
this.videoCard = videoCard;
}
}
客户端测试类
/**
* @author 付玉伟
* @time 2015-2-12 下午10:37:57
* @param args
*/
public static void main(String[] args) {
// 创建调停者——主板
MainBoard mediator = new MainBoard();
// 创建同事类
CdDriver cd = new CdDriver(mediator);
Cpu cpu = new Cpu(mediator);
SoundCard sc = new SoundCard(mediator);
VideoCard vc = new VideoCard(mediator);
// 让调停者通知所有同事
mediator.setCdDriver(cd);
mediator.setCpu(cpu);
mediator.setSoundCard(sc);
mediator.setVideoCard(vc);
// 开始看电影
cd.readCD();
}
执行结果:
调停者模式的优点
松散耦合:通过把多个同事对象之间的交互封装到调停者对象中,从而使同事对象之间松散耦合,同事可以独立的变化和复用
集中控制交互:扩展调停者对象,同事类不需修改
多对多变成一对多
缺点
多度集中化,如果同事对象交互非常多而且复杂,导致调停者对象难以维护