概念
定义
中介者模式,就是用一个中介对象来封装一系列的对象交互。中介者使得相关对象之间复杂的沟通和控制得到缓解,不需要显式的相互引用,从而使他们耦合松散。核心:封装对象间的交互
结构
中介者模式有两个角色,“同事类”和“中介者”。
同事类是平行关系,一般是实现自己的业务,当需要与其他同事进行通信的时候,就通知该同事持有的中介者,中介者再负责交互,所以每个同事类都应该知道中介者
中介者负责同事之间的交互,协调他们之间的关系,所以中介者需要知道他负责交互的同事对象。
关键说明
事实上上面已经讲述了中介者和同事类的关系。那么重点就在于,中介者怎么跟同事类交互,同事类又怎么在自身需要和其他同事类交互的时候,能够通知中介者。
其实也相当简单,只需要在同事类需要交互的时候,调用同事类的父类接口,找到中介者,将自身传给中介者的某个方法。由中介者来控制逻辑,协调交互就行了。
中介者也只需要在这个方法内判断,该同事类是想跟哪个同事类交互。因为中介者知道他旗下所有的同事类,所以只需要调用A同事类想要交互的B同事类方法即可
所以核心就是中介者的这个通知接口,只要设计好,定义好,其他同事类来调用这个方法接口即可
小实例
中介者接口
/**
* 中介者,定义各个同事对象通信的接口
*/
public interface Mediator {
/**
* 同事对象在自身改变的时候来通知中介者的方法,
* 让中介者去负责相应的与其他同事对象的交互
* @param colleague 同事对象自身,好让中介者对象通过对象实例
* 去获取同事对象的状态
*/
public void changed(Colleague colleague);
}
同事类接口
/**
* 同事类的抽象父类
*/
public abstract class Colleague {
/**
* 持有中介者对象,每一个同事类都知道它的中介者对象
*/
private Mediator mediator;
/**
* 构造方法,传入中介者对象
* @param mediator 中介者对象
*/
public Colleague(Mediator mediator) {
this.mediator = mediator;
}
/**
* 获取当前同事类对应的中介者对象
* @return 对应的中介者对象
*/
public Mediator getMediator() {
return mediator;
}
}
实体中介者类
/**
* 具体的中介者实现
*/
public class ConcreteMediator implements Mediator {
/**
* 持有并维护同事A
*/
private ConcreteColleagueA colleagueA;
/**
* 持有并维护同事B
*/
private ConcreteColleagueB colleagueB;
/**
* 设置中介者需要了解并维护的同事A对象
* @param colleague 同事A对象
*/
public void setConcreteColleagueA(ConcreteColleagueA colleague) {
colleagueA = colleague;
}
/**
* 设置中介者需要了解并维护的同事B对象
* @param colleague 同事B对象
*/
public void setConcreteColleagueB(ConcreteColleagueB colleague) {
colleagueB = colleague;
}
public void changed(Colleague colleague) {
//某个同事类发生了变化,通常需要与其他同事交互
if(colleague==colleagueA){
colleagueB.someOperation();
}
//具体协调相应的同事对象来实现协作行为
}
}
同事类实体
/**
* 具体的同事类A
*/
public class ConcreteColleagueA extends Colleague {
public ConcreteColleagueA(Mediator mediator) {
super(mediator);
}
/**
* 示意方法,执行某些业务功能
*/
public void someOperation() {
//在需要跟其他同事通信的时候,通知中介者对象
System.out.println("我是A,想和B通信");
getMediator().changed(this);
}
}
/**
* 具体的同事类B
*/
public class ConcreteColleagueB extends Colleague {
public ConcreteColleagueB(Mediator mediator) {
super(mediator);
}
/**
* 示意方法,执行某些业务功能
*/
public void someOperation() {
//在需要跟其他同事通信的时候,通知中介者对象
System.out.println("我是B");
getMediator().changed(this);
}
}
测试类
public class Client {
public static void main(String[] args) {
ConcreteMediator mediator = new ConcreteMediator();
ConcreteColleagueA a = new ConcreteColleagueA(mediator);
ConcreteColleagueB b = new ConcreteColleagueB(mediator);
mediator.setConcreteColleagueA(a);
mediator.setConcreteColleagueB(b);
a.someOperation();
}
}
其重点就是中介者的changed()接口,所有的同事需要交互的时候,都会调用它自身的中介者的这个接口。
中介者在这个接口对调用的同事进行判断,分析他们想要和谁交互
具体实例
这是一个主板和主板上各个组件进行数据交互的实例。
组件有光驱,CPU,声卡,显卡四个组件。他们之间不进行直接交互,而是通过主板这个中介进行数据通信交互。
从光驱读取数据,传给中介者。中介者得到数据后,传给CPU。CPU分析数据,得出声音数据和影像数据。然后通知中介者。中介者得到了声音数据和影像数据,再分别通知声卡和显卡工作,最后完成了整个体系的交互
中介者接口
/**
* 中介者对象的接口
*/
public interface Mediator {
/**
* 同事对象在自身改变的时候来通知中介者的方法,
* 让中介者去负责相应的与其他同事对象的交互
* @param colleague 同事对象自身,好让中介者对象通过对象实例
* 去获取同事对象的状态
*/
public void changed(Colleague colleague);
}
同事类父类
/**
* 同事类的抽象父类
*/
public abstract class Colleague {
/**
* 持有中介者对象,每一个同事类都知道它的中介者对象
*/
private Mediator mediator;
/**
* 构造方法,传入中介者对象
* @param mediator 中介者对象
*/
public Colleague(Mediator mediator) {
this.mediator = mediator;
}
/**
* 获取当前同事类对应的中介者对象
* @return 对应的中介者对象
*/
public Mediator getMediator() {
return mediator;
}
}
同事类实例
/**
* 光驱类,一个同事类
*/
public class CDDriver extends Colleague{
public CDDriver(Mediator mediator) {
super(mediator);
}
/**
* 光驱读取出来的数据
*/
private String data = "";
/**
* 获取光驱读取出来的数据
* @return 光驱读取出来的数据
*/
public String getData(){
return this.data;
}
/**
* 读取光盘
*/
public void readCD(){
//逗号前是视频显示的数据,逗号后是声音
this.data = "设计模式,值得好好研究";
//通知主板,自己的状态发生了改变
this.getMediator().changed(this);
}
}
/**
* CPU类,一个同事类
*/
public class CPU extends Colleague{
public CPU(Mediator mediator) {
super(mediator);
}
/**
* 分解出来的视频数据
*/
private String videoData = "";
/**
* 分解出来的声音数据
*/
private String soundData = "";
/**
* 获取分解出来的视频数据
* @return 分解出来的视频数据
*/
public String getVideoData() {
return videoData;
}
/**
* 获取分解出来的声音数据
* @return 分解出来的声音数据
*/
public String getSoundData() {
return soundData;
}
/**
* 处理数据,把数据分成音频和视频的数据
* @param data 被处理的数据
*/
public void executeData(String data){
//把数据分解开,前面的是视频数据,后面的是音频数据
String [] ss = data.split(",");
this.videoData = ss[0];
this.soundData = ss[1];
//通知主板,CPU的工作完成
this.getMediator().changed(this);
}
}
/**
* 声卡类,一个同事类
*/
public class SoundCard extends Colleague{
public SoundCard(Mediator mediator) {
super(mediator);
}
/**
* 按照声频数据发出声音
* @param data 发出声音的数据
*/
public void soundData(String data){
System.out.println("画外音:"+data);
}
}
/**
* 显卡类,一个同事类
*/
public class VideoCard extends Colleague{
public VideoCard(Mediator mediator) {
super(mediator);
}
/**
* 显示视频数据
* @param data 被显示的数据
*/
public void showData(String data){
System.out.println("您正观看的是:"+data);
}
}
中介者实体类
/**
* 主板类,实现中介者接口
*/
public class MotherBoard implements Mediator{
/**
* 需要知道要交互的同事类——光驱类
*/
private CDDriver cdDriver = null;
/**
* 需要知道要交互的同事类——CPU类
*/
private CPU cpu = null;
/**
* 需要知道要交互的同事类——显卡类
*/
private VideoCard videoCard = null;
/**
* 需要知道要交互的同事类——声卡类
*/
private SoundCard soundCard = null;
public void setCdDriver(CDDriver cdDriver) {
this.cdDriver = cdDriver;
}
public void setCpu(CPU cpu) {
this.cpu = cpu;
}
public void setVideoCard(VideoCard videoCard) {
this.videoCard = videoCard;
}
public void setSoundCard(SoundCard soundCard) {
this.soundCard = soundCard;
}
public void changed(Colleague colleague) {
if(colleague == cdDriver){
//表示光驱读取数据了
this.opeCDDriverReadData((CDDriver)colleague);
}else if(colleague == cpu){
//表示CPU处理完了
this.opeCPU((CPU)colleague);
}
}
/**
* 处理光驱读取数据过后与其他对象的交互
* @param cd 光驱同事对象
*/
private void opeCDDriverReadData(CDDriver cd){
//1:先获取光驱读取的数据
String data = cd.getData();
//2:把这些数据传递给CPU进行处理
this.cpu.executeData(data);
}
/**
* 处理CPU处理完数据后与其他对象的交互
* @param cpu CPU同事类
*/
private void opeCPU(CPU cpu){
//1:先获取CPU处理过后的数据
String videoData = cpu.getVideoData();
String soundData = cpu.getSoundData();
//2:把这些数据传递给显卡和声卡展示出来
this.videoCard.showData(videoData);
this.soundCard.soundData(soundData);
}
}
测试类
public class Client {
public static void main(String[] args) {
//1:创建中介者——主板对象
MotherBoard mediator = new MotherBoard();
//2:创建同事类
CDDriver cd = new CDDriver(mediator);
CPU cpu = new CPU(mediator);
VideoCard vc = new VideoCard(mediator);
SoundCard sc = new SoundCard(mediator);
//3:让中介者知道所有的同事
mediator.setCdDriver(cd);
mediator.setCpu(cpu);
mediator.setVideoCard(vc);
mediator.setSoundCard(sc);
//4:开始看电影,把光盘放入光驱,光驱开始读盘
cd.readCD();
}
}