1. 定义
用一个中介者对象来封装了一个系列对象的交互,中介者使得各个对象可以不需要显式的引用,而且可以独立改变对象之间的交互。
中介者模式思路很简单,中介者模式中通过引入一个中介者对象,让其他对象与中介者对象进行交互,而中介者对象知道如何和所有对象交互,这样对象之间的交互关系就没有了,从而实现对象之间解耦。
每个同事对象发生了变化,不需要知道这样会引起其他对象什么变化,只需要通知中介者,由中介者去与其他对象交互。这样的松耦合带来的好处是,同事对象之间的交互关系减少,而且有利于功能的修改和扩展。
2. 类图
Mediator:中介者接口,定义了同事对象之间交互的方法,可以是比较通用的方法,比如change,也可以是小范围的交互方法。
ConcreteMediator:中介者实体,实现接口中定义的方法,持有同事对象的引用,负责协调同事对象之间的交互。
Colleague:同事类,通常抽象为抽象类,主要功能是约束同事对象的类型,实现一些公用的方法。
ColleagueA、ColleagueB:同事实体,实现各自的业务,需要与其他同事对象交互时,与中介者通信,让中介者处理交互。
3. 实例
package com.jerry.designpattern; /** * 中介者 * @author Jerry * @date 2015年1月20日 上午11:05:00 */ public interface Mediator { /** * * @param mediator */ void changed(Colleague colleague); } package com.jerry.designpattern; /** * * @author Jerry * @date 2015年1月20日 上午11:26:05 */ public class MainBoard implements Mediator{ private CDDriver cdDriver; private CPU cpu; private VideoCard videoCard; private SoundCard soundCard; 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; } @Override public void changed(Colleague colleague) { // TODO Auto-generated method stub if (colleague instanceof CDDriver) { String data = cdDriver.getData(); cpu.executeData(data); } else if (colleague instanceof CPU) { videoCard.showVideo(cpu.getVideoData()); soundCard.soundData(cpu.getSoundData()); } } } package com.jerry.designpattern; /** * * @author Jerry * @date 2015年1月20日 上午11:04:43 */ 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; } } package com.jerry.designpattern; /** * * @author Jerry * @date 2015年1月20日 上午11:14:26 */ 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[] ss = data.split(","); this.videoData = ss[0]; this.soundData = ss[1]; super.getMediator().changed(this); } } package com.jerry.designpattern; /** * * @author Jerry * @date 2015年1月20日 上午11:06:49 */ public class CDDriver extends Colleague{ private String data; public CDDriver(Mediator mediator) { super(mediator); } public void readCD() { this.data = "设计模式,值得好好研究"; super.getMediator().changed(this); } public String getData() { return this.data; } } package com.jerry.designpattern; /** * * @author Jerry * @date 2015年1月20日 上午11:23:19 */ public class SoundCard extends Colleague{ public SoundCard(Mediator mediator) { super(mediator); } public void soundData(String data) { System.out.println("画外音:" + data); } } package com.jerry.designpattern; /** * * @author Jerry * @date 2015年1月20日 上午11:20:31 */ public class VideoCard extends Colleague{ public VideoCard(Mediator mediator) { super(mediator); } public void showVideo(String data) { System.out.println("正在观看:" + data); } } package com.jerry.designpattern; /** * * @author Jerry * @date 2015年1月20日 上午11:31:44 */ public class Client { public static void main(String[] args) { MainBoard mainBoard = new MainBoard(); CDDriver cdDriver = new CDDriver(mainBoard); CPU cpu = new CPU(mainBoard); VideoCard videoCard = new VideoCard(mainBoard); SoundCard soundCard = new SoundCard(mainBoard); mainBoard.setCdDriver(cdDriver); mainBoard.setCpu(cpu); mainBoard.setVideoCard(videoCard); mainBoard.setSoundCard(soundCard); cdDriver.readCD(); } }
4. 认识中介者模式
中介者模式功能非常简单,就是封装对象之间的交互,如果一个对象的操作,会引起其他相关对象的改变,或者某个操作需要引起对象的后续和连续操作,而这个对象不想自己处理这些关系,那就可以交给中介者来处理,把所有麻烦都交给中介者,只在需要的时候通知中介者,其他的让中介者来处理就可以了。
5. 中介者优缺点
优点:松散耦合,集合控制交互,多对多变成一对多
缺点:过度集中化,如果同事之间的交互非常多,而且比较复杂,全部集中在中介者中,会使中介者变得十分复杂,难以管理和维护。