目录
场景
思考
解决思路
模式讲解
调用示意图
中介者模式的优缺点
中介者模式的本质
何时选用
场景
如果没有主板,电脑各个配件怎么交互呢?
有些配件接口不同,必须把数据接口进行转换才能匹配上,无敌复杂。
有了主板之后就是下面这个样子
思考
软件开发中针对,内部复杂的我们可以找一个中介者,让中介者去处理这些事情。
解决思路
白话解析:
1.分为中介者和同事两个层级。同事们都和我交互,而我知道怎么把同事的交互跟别人的串联起来,但单个同事你不用管我是怎么跟人交互的,你做好自己的就可以了。
2.同事在处理完自己的事情后,你得告诉中介者你做了改变,让我心里有数,不能自己想做什么做什么,闷头干大事不交流。
模式讲解
结构图
代码示例:
Mediator
package day09中介者模式;
/**
* 中介者对象的接口
*/
public interface Mediator {
/**
* 同事对象在自身改变的时候来通知中介者的方法,
* 让中介者去负责相应的与其他同事对象的交互
* @param colleague 同事对象自身,好让中介者对象通过对象实例去获取同事对象的状态
*/
public void changed(Colleague colleague);
}
ConcreteMediator
package day09中介者模式;
import day09中介者模式.同事.CDDriver;
import day09中介者模式.同事.CPU;
import day09中介者模式.同事.SoundCard;
import day09中介者模式.同事.VideoCard;
/**
* 相当于主板,实现中介者对象
*/
public class MediatorImpl implements Mediator {
/**
* 需要知道交互的同时类-光驱类
*/
private CDDriver cdDriver = null;
/**
* 需要知道交互的同时类-CPU类
*/
private CPU cpu = null;
/**
* 需要知道交互的同时类-显卡类
*/
private VideoCard videoCard = null;
/**
* 需要知道交互的同时类-声卡类
*/
private SoundCard soundCard = null;
/**
* 方法重写
*
* @param colleague 同事对象自身,好让中介者对象通过对象实例去获取同事对象的状态
*/
@Override
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
*/
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 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 VideoCard getVideoCard() {
return videoCard;
}
public void setVideoCard(VideoCard videoCard) {
this.videoCard = videoCard;
}
public SoundCard getSoundCard() {
return soundCard;
}
public void setSoundCard(SoundCard soundCard) {
this.soundCard = soundCard;
}
}
Colleague,我这里定义成抽象父类
package day09中介者模式;
/**
* 所有同事的抽象父类的定义
*/
public abstract class Colleague {
/**
* 持有中介者对象,每一个同事都知道它的中介者对象
*/
private Mediator mediator;
/**
* 构造方法,传入中介者对象
* @param mediator
*/
public Colleague(Mediator mediator){
this.mediator = mediator;
}
/**
* 获取当前同时类对应的中介者对象
* @return
*/
public Mediator getMediator(){
return mediator;
}
}
同事子类 分别为光驱 cpu 显卡 声卡
package day09中介者模式.同事;
import day09中介者模式.Colleague;
import day09中介者模式.Mediator;
/**
* 光驱类
*/
public class CDDriver extends Colleague {
public CDDriver(Mediator mediator) {
super(mediator);
}
/**
* 光驱读取出来的数据
*/
private String data = "";
/**
* 获取光驱读取出来的数据
*/
public String getData(){
return this.data;
}
/**
* 读取光盘
*/
public void readCD(){
// 逗号前是视频显示的数据,逗号后是声音
this.data = "设计模式,值得好好研究";
// 通知主板,自己的状态发生了改变
this.getMediator().changed(this);
}
}
package day09中介者模式.同事;
import day09中介者模式.Colleague;
import day09中介者模式.Mediator;
/**
* CPU类
*/
public class CPU extends Colleague {
public CPU(Mediator mediator) {
super(mediator);
}
/**
* 分解出来的视频数据
*/
private String videoData = "";
/**
* 分解出来的声音数据
*/
private String soundData = "";
/**
* 获取分解出来的视频数据
*/
public String getVideoData() {
return videoData;
}
/**
* 获取分解出来的声音数据
*/
public String getSoundData() {
return soundData;
}
public void executeData(String data) {
// 把数据分解开
String[] split = data.split(",");
this.videoData = split[0];
this.soundData = split[1];
// 通知主板,CPU的工作完成
this.getMediator().changed(this);
}
}
package day09中介者模式.同事;
import day09中介者模式.Colleague;
import day09中介者模式.Mediator;
/**
* 显卡类
*/
public class VideoCard extends Colleague {
public VideoCard(Mediator mediator) {
super(mediator);
}
/**
* 显示视频数据
* @param data
*/
public void showData(String data){
System.out.println("您正观看的是:" + data);
}
}
package day09中介者模式.同事;
import day09中介者模式.Colleague;
import day09中介者模式.Mediator;
/**
* 声卡类
*/
public class SoundCard extends Colleague {
public SoundCard(Mediator mediator) {
super(mediator);
}
/**
* 按照声频数据发出声音
* @param data
*/
public void soundData(String data){
System.out.println("画外音:" + data);
}
}
Client
package day09中介者模式;
import day09中介者模式.同事.CDDriver;
import day09中介者模式.同事.CPU;
import day09中介者模式.同事.SoundCard;
import day09中介者模式.同事.VideoCard;
public class Client {
public static void main(String[] args) {
// 1.创建中介者-主板对象
MediatorImpl mediator = new MediatorImpl();
// 2.创建同事类
CDDriver cdDriver = new CDDriver(mediator);
CPU cpu = new CPU(mediator);
VideoCard videoCard = new VideoCard(mediator);
SoundCard soundCard = new SoundCard(mediator);
// 3.让中介者知道所有的同事
mediator.setCdDriver(cdDriver);
mediator.setCpu(cpu);
mediator.setVideoCard(videoCard);
mediator.setSoundCard(soundCard);
// 4.开始看电影
cdDriver.readCD();
}
}
首先有一个中介者接口Mediator,其中有一个changed方法,这个方法代表同事们发生变化后要通知我,然后是MediatorImpl实现定义的接口(相当于主板,并且定义了交互方法,需要注意的是我这个主板肯定要包含cpu,显卡,声卡,驱动等同事的,不然我的信息也没法转交)
实现changed的方法,就是怎么交互,从上到下,如果传过来的是驱动的信息,怎么搞,如果传过来是cpu的信息,怎么搞。怎么判断顺序呢?
我们自己定义的,进这个方法后
this.getMediator().changed(this); 有这么一句话,就是将自身的改变后的本身告诉中介者。
然后就在进入这个方法
判断进来的是什么实体?哦,是驱动
调用第一个if执行。
然后就进入这里 executeData
CPU处理完也是要告知中介者,我完成了,剩下的交给你做吧
就进入了第二个if。
showData
soundData
客户端使用:
1.先创建中介者
2.增加同事类
3.让中介者知道所有同事 set进去
4.开始执行第一步
调用示意图
中介者模式的优缺点
中介者模式的本质
封装交互