中介者模式的介绍
中介者模式是行为型模式这一,在日常生活中,比如两口子吵架,孩子和双方的父母会劝架,孩子和双方的父母就称有中介者的意思,就是“和事佬”,也就是说调解两个起争端的人。而中介绍者模式比这个例子要复杂的多,上面的例子只是涉及到2个人的,中介者模式要涉及的对象是多个。多个对象之间的交互关系,是很复杂的,是网状的关系,中介者就是要把这种多对多的关系转化为一对多的关系,就是转化为星状结构,如下图
中介模式的定义
中介者模式包装了一系列对象的相互交互作用的方式,使得这些对象不必相互明显作用。从而使它们可以松散耦合,当某些对象之间的作用发生改变时,不会立即影响其他的一些对象之间的作用,保证这些作用可以彼此独立的变化,中介者模式将多对多的相互作用转化为一对多的相互作用。中介者模式将对象的行为和协作抽象化,把对象在小尺度的行为上与其他对象的相互作用分开处理
中介者模式的使用场景
当对象之间的交互操作很多且每个对象的行为操作都依赖彼此时,为防止在修改一个对象的行为时,同时涉及修改很多其它对象的行为,可采用中介者模式,来解决紧耦合问题。该模式将对象之间的多对多关系变成一对多关系,中介者对象将系统从网状系统变成以中介者为中心的星状形结构,达到降低系统的复杂性,提高可扩展性的作用。
中介者模式简单的实现,比如我们每天都在使用的电脑就是一个中介者的例子,以电脑主机为例,我们都知道电脑主机分为主要的几块:CPU,内存,显卡,IO设备等我们需要一样东西将这些零件都整合起来变成一个完整的整体,这个东西就是主板,在这里主板就起到了中介者的使用,连接CPU,内存,显示和IO设备等,任何两个模式之间的通信都会经过主板去协调,这里以读取光盘为例,来看看主板是如何充当一个中介者角色的。首先定义一个抽象的中介者。
/**
* 抽象中介者
*/
public abstract class Mediator {
public abstract void changed(Colleague c);
}
抽象中介者只是定义了一个抽象的接口方法,具体的同事类通过该方法来通知中介者自身的状态改变。而具体的中介者这里就是主板,由它负责联系各个具体同事类,也就是CPU,内存,显卡,IO设备等
/**
* 具体的中介者,也就是主板
*/
public class MainBoard extends Mediator{
private CDDevice cdDevice;
private CPU cpu;
private SoundCard soundCard;
private GraphicsCard graphicsCard;
public void setCdDevice(CDDevice cdDevice) {
this.cdDevice = cdDevice;
}
public void setCpu(CPU cpu) {
this.cpu = cpu;
}
public void setSoundCard(SoundCard soundCard) {
this.soundCard = soundCard;
}
public void setGraphicsCard(GraphicsCard graphicsCard) {
this.graphicsCard = graphicsCard;
}
public void changed(Colleague c){
if(c == cdDevice){
handleCD((CDDevice) c);
}else if(c == cpu){
handleCPU((CPU) c);
}
}
//处理光驱读取数据后与其他设备的交互
private void handleCD(CDDevice cdDevice){
cpu.decodeData(cdDevice.read());
}
//处理CPU读取数据后与其它设备的交互
private void handleCPU(CPU cpu){
soundCard.soundPlay(cpu.getDataSound());
graphicsCard.videoPlay(cpu.getDataVideo());
}
}
抽象同事类里只有一个抽象中介者的引用,我们在构造方法中为其赋值
/**
*
* 同事类(也就是多个交互对象的基类)
*/
public abstract class Colleague {
protected Mediator mediator; //每一个同事都知道其中介者
public Colleague(Mediator mediator){
this.mediator = mediator;
}
}
接下来就是每个具体的同事类了,在这个例子中就是CPU,内存,显卡,IO设备等。
/**
* CPU
*/
public class CPU extends Colleague{
private String dataVideo;
private String dataSound;
public CPU(Mediator mediator) {
super(mediator);
}
//获取视频数据
public String getDataVideo(){
return dataVideo;
}
public String getDataSound(){
return dataSound;
}
//解码数据
public void decodeData(String data){
String[] tmp = data.split(",");
dataVideo = tmp[0];
dataSound = tmp[1];
mediator.changed(this);
}
}
显卡类:
/**
* 显卡类
*/
public class GraphicsCard extends Colleague {
public GraphicsCard(Mediator mediator) {
super(mediator);
}
//播放视频
public void videoPlay(String data) {
System.out.println("视频:" + data);
}
}
声卡类:
/**
* 声卡类
*/
public class SoundCard extends Colleague {
public SoundCard(Mediator mediator) {
super(mediator);
}
//播放音频
public void soundPlay(String data) {
System.out.println("音频:" + data);
}
}
CD类:
/**
* CD 类
*/
public class CDDevice extends Colleague{
private String data; //视频数据
public CDDevice(Mediator mediator) {
super(mediator);
}
//读取视频数据
public String read(){
return data;
}
//加载视频数据
public void load(){
data = "视频数据,音频数据";
//通知中介者,也就是主板数据改变
mediator.changed(this);
}
}
最后是测试类
/**
* 中介者模式 测试类
*/
public class MediatorTest {
public static void test(){
//构造一个主板
MainBoard mediator = new MainBoard();
//分别构造各种零件
CDDevice cdDevice = new CDDevice(mediator);
CPU cpu = new CPU(mediator);
GraphicsCard graphicsCard = new GraphicsCard(mediator);
SoundCard soundCard = new SoundCard(mediator);
//将各个零件安装到主板
mediator.setCdDevice(cdDevice);
mediator.setCpu(cpu);
mediator.setSoundCard(soundCard);
mediator.setGraphicsCard(graphicsCard);
//完成后可以开始播放片了
cdDevice.load();
}
}
可见,可种零件的交互不是直接交互了,都是通过主板进行交互,这里主板就充当了一个中介者的作用。中介者模式降低了对象之间关系的复杂度