如有转载,请申明:
转载至 http://blog.csdn.net/qq_35064774/article/details/52096987
1 什么是调停者模式
调停者模式包装了一系列对象相互作用的方式,使得这些对象不必互相明显引用。从而使它们可以松散的耦合。当这些对象中的某些对象之间的相互作用发生改变时,不会立即影响到其他的一些对象之间的相互作用。从而保证了这些相互作用可以彼此独立地变化。
简单来说就是许多对象之间关系错综复杂,如果让这些对象直接联系的话,复杂度和耦合度很高。这时候专门设立一个调停者,让所有对象只喝调停者联系,不必关心其他对象。这样可以降低对象之间的复杂度,但增加了调停者的复杂度。所以要谨慎使用。
2 如何实现调停者模式
同样以一个简单的例子作为入口。
* 假设在电脑上播放视频需要以下步骤。
* 硬盘上读取数据
* 把数据交给CPU处理
* CPU把数据分别给显卡和声卡进行播放
* 要求通过主板来统一管理这些对象的调用
我们可以看硬盘、cpu、显卡和声卡之间的调用关系颇为麻烦,为此专门设立一个主板来管理这些关系,其他设备就只需要和主板打交道了。
为此我们先抽象一个调停者的接口出来,如果只有一个调停者的话,也可以直接设计对象,这里为了做个完整的示范,就设计了接口。
package com.ittianyu.mediator;
public interface Mediator {
void changed(Colleague colleague);
}
这个接口的changed方法,是其他对象用来通知调停者自身发生改变的方法。比如硬盘读取完成时,调用这个方法来通知主板进行下一步操作。
接下来为了统一接口,我们定义一个设备抽象类,也就是同事类(相对于调停者来说,其他类就是同事关系)。
package com.ittianyu.mediator;
public abstract class Colleague {
protected Mediator mediator;
public Colleague(Mediator mediator) {
super();
this.mediator = mediator;
}
public Mediator getMediator() {
return mediator;
}
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
}
接下来是具体设备类的定义。
package com.ittianyu.mediator;
public class HardDisk extends Colleague {
private String data;
public HardDisk(Mediator mediator) {
super(mediator);
}
public String getData() {
return data;
}
/**
* 读取数据,然后通知主板读取完成
*/
public void read() {
data = "vedio1, sound2";
mediator.changed(this);
}
}
package com.ittianyu.mediator;
public class CPU extends Colleague {
private String videoData;
private String soundData;
public String getVideoData() {
return videoData;
}
public String getSoundData() {
return soundData;
}
public CPU(Mediator mediator) {
super(mediator);
}
/**
* 处理数据,并通知主板数据处理完成
* @param data 需要处理的数据
*/
public void dealWithData(String data) {
// 以逗号分隔文本,假设逗号之前的是视频数据,之后的是音频数据
String[] strings = data.split(",");
if(strings.length < 2)
return;
videoData = strings[0];
soundData = strings[1];
mediator.changed(this);
}
}
package com.ittianyu.mediator;
public class SoundCard extends Colleague {
public SoundCard(Mediator mediator) {
super(mediator);
}
public void play(String sound) {
System.out.println("play sound " + sound);
}
}
package com.ittianyu.mediator;
public class VideoCard extends Colleague {
public VideoCard(Mediator mediator) {
super(mediator);
}
public void play(String vedio) {
System.out.println("play vedio " + vedio);
}
}
然后是主板的定义,也就是调停者的具体实现类
package com.ittianyu.mediator;
public class MainBoard implements Mediator {
private CPU cpu;
private SoundCard soundCard;
private VideoCard videoCard;
private HardDisk hardDisk;
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;
}
public HardDisk getHardDisk() {
return hardDisk;
}
public void setHardDisk(HardDisk hardDisk) {
this.hardDisk = hardDisk;
}
/**
* 当收到设备工作完成时
* 如果是硬盘,把数据交给cpu处理
* 如果是cpu,把数据传给声卡和显卡播放
*/
@Override
public void changed(Colleague colleague) {
if(colleague instanceof HardDisk) {
this.dealWithData((HardDisk)colleague);
} else if(colleague instanceof CPU) {
this.playData((CPU)colleague);
}
}
/**
* 把数据传给声卡和显卡播放
*/
private void playData(CPU colleague) {
videoCard.play(cpu.getVideoData());
soundCard.play(cpu.getSoundData());
}
/**
* 把数据交给cpu处理
*/
private void dealWithData(HardDisk colleague) {
cpu.dealWithData(colleague.getData());
}
}
这个类里面,我们需要负责协调好其他对象的关系。
最后是测试类。
package com.ittianyu.mediator;
public class Test {
public static void main(String[] args) {
MainBoard mediator = new MainBoard();
// create colleagues
Colleague cpu = new CPU(mediator);
Colleague soundCard = new SoundCard(mediator);
Colleague videoCard = new VideoCard(mediator);
Colleague hardDisk = new HardDisk(mediator);
mediator.setCpu((CPU) cpu);
mediator.setSoundCard((SoundCard) soundCard);
mediator.setVideoCard((VideoCard) videoCard);
mediator.setHardDisk((HardDisk) hardDisk);
((HardDisk)hardDisk).read();
}
}
3 在什么情况下不应该使用调停者模式
* 不应当在责任划分混乱时使用。
* 不应当对“数据类”和“方法类”使用。
4 调停者模式的优点和缺点
优点:
* 可以较少使用静态的继承关系,使得具体同事类可以更加容易地被复用。
* 适当使用调停者模式可以避免同事类对象之间的过度耦合,使得调停类与同事类可以相对独立地演化。
* 调停者模式将多对多的相互作用转化为一对多的相互作用,使得对象之间的关系更加易于维护和理解。
* 调停者模式将对象的行为和协作抽象化,把对象在小尺度的行为上与其他对象的相互作用分开处理。
缺点:
* 调停者模式降低了同事对象的复杂性,代价是增加了调停者类的复杂性。当然,在很多情况下,设置一个调停者并不比不设置一个调停者更好。
* 调停者类经常充满了各个具体同事类的关系协调代码,这种代码常常是不能复用的。因此,具体同事类的复用是以调停者类的不可复用为代价的。