一、模式介绍
Mediator模式,中介者模式,或叫调停者模式,它的主要作用在于将有复杂调用依赖关系的类解耦和。中介者封装了一系列类的交互行为,它使得类和类之间的多对多交互变成了和类和调停者者之间多对一的交互,这种行为的封装使得类之间的调用依赖系更加 集中化 和 易控化,使得类与类之间变得松耦合化。中介者,就像一个交通枢纽,就类似现实生活中的中介一样,承担着连通作用。
从原理图也可以看出,中介者 处于 多个交互类的中间位置,在他们之间进行调度转发。
在下面的示例代码中,项目经理作为中介者,架构师、程序员、测试员作为同事,他们之间的复杂关系为:架构是设计完成要交给程序员开发,程序开发中发现设计错误要交给设计师修改(修改后再交给程序员开发),开发完成后要交给测试员测试,测试发现开发错误要交给程序员修改,发现设计错误要交给架构师修改,等等,由于工作流交互非常复杂且可能发生变化,故把工作的流程控制全部交给了项目管理员,项目管理员全权负责工作该交给谁来进行下一步,因此通常管理员(中介者)必需知晓各位同事的具体能力(类的方法细节)。
中介者,更多强调的是一种集中管理的思想,其实现约束基本没有,也就非常之灵活,它不像其它模式必需依赖抽象和接口。
即便是多个毫无关系,他们直接有负责的调用依赖就可以使用中介者模式。
二、原理图
三、示例代码
import java.util.*; enum EventType { DESIGN,DEVELOP,TEST } //中介者 interface Mediator { int PROJECT_BEGIN = 0; int DESIGN_OK = 1; int DESIGN_ERROR = 2; int DEVELOP_OK = 3; int DEVELOP_ERROR = 4; int PROJECT_OVER = 5; void registerColleague(Colleague c, EventType interest); void changed(Colleague from, int arg); // 可能需要一些参数 } //项目管理员,中介者角色,负责工作调度 class ProjectManager implements Mediator { Map<EventType, Set<Colleague>> colleagueInterest;; public ProjectManager() { colleagueInterest = new HashMap<EventType, Set<Colleague>>(); for (EventType eventType: EventType.values()) { colleagueInterest.put(eventType, new HashSet()); } } @Override public void registerColleague(Colleague c, EventType interest) { colleagueInterest.get(interest).add(c); } @Override public void changed(Colleague from, int arg) { Set<Colleague> listeners = colleagueInterest.get(from.getSubject()); for (Colleague colleague : listeners) { //这里使用了一个 参数 技巧,用以指定被调度者,可以换成其它方式来指定被调度者(被通知者) colleague.doWork(arg); } } /** * 也可以不使用上述的 “观察者” 通知模式, * 改成:直接调用对应的方法,如:processDesign,processDevelop,processTest 等等 * 或者类似访问者模式:process(Designer d),process(Programmer p),processTester(Tester t) 等等 * * 总之:中介者(调停者,应该知晓每一个“同事”的“细节”) !!! */ } //同事,直接与中介交流工作进展与完成情况 abstract class Colleague { EventType subject; Mediator mediator; public Colleague(EventType subject, Mediator mediator) { this.mediator = mediator; this.subject = subject; } protected void registerInterest(EventType interest) { mediator.registerColleague(this, interest); } EventType getSubject() { return subject; } abstract void doWork(int arg); } class Designer extends Colleague { public Designer(Mediator mediator) { super(EventType.DESIGN, mediator); } public void doWork(int arg) { if (arg == Mediator.PROJECT_BEGIN || arg == Mediator.DESIGN_ERROR) { System.out.println("架构师收到:" + arg); System.out.println("架构师开始设计,程序设计工作完成!"); mediator.changed(this, Mediator.DESIGN_OK);// 告诉中介一声,后续工作等其它事不用关心 } } } class Programmer extends Colleague { public Programmer(Mediator mediator) { super(EventType.DEVELOP, mediator); } public void doWork(int arg) { if (arg == Mediator.DESIGN_OK || arg == Mediator.DEVELOP_ERROR) { System.out.println("程序员收到:" + arg); System.out.println("研发人员进行开发...开发完成!"); // 告诉中介一声,后续工作等其它事不用关心 if (new Random().nextBoolean()) { mediator.changed(this, Mediator.DEVELOP_OK); } else { mediator.changed(this, Mediator.DESIGN_ERROR); } } } } class Tester extends Colleague { public Tester(Mediator mediator) { super(EventType.TEST, mediator); } public void doWork(int arg) { if (arg == Mediator.DEVELOP_OK) { System.out.println("测试人员正在测试...测试完成!"); // 告诉中介一声,后续工作等其它事不用关心 switch (new Random().nextInt(2)) { case 0: mediator.changed(this, Mediator.PROJECT_OVER); break; case 1: mediator.changed(this, Mediator.DESIGN_ERROR); break; default: mediator.changed(this, Mediator.DEVELOP_ERROR); } } } } /** * 设计师,开发完成后通知研发进行开发 * 程序员,开发过程中遇到问题可以通知设计师,开发完成通知测试员 * 测试员,测试问题通知研发或设计师 */ public class T { public static void main(String[] args) { Mediator mediator = new ProjectManager(); // 管理者,中介者 Colleague designer = new Designer(mediator); // 设计师,与中介者打交道 designer.registerInterest(EventType.DEVELOP); designer.registerInterest(EventType.TEST); Colleague programmer = new Programmer(mediator); // 程序员,与中介者打交道 programmer.registerInterest(EventType.DESIGN);// 程序员,注册到中介,之后可被中介调度 Colleague tester = new Tester(mediator); // 测试员,与中介者打交道 tester.registerInterest(EventType.DEVELOP);// 测试员,注册到中介,之后可被中介调度 // 设计师首先设计程序 designer.doWork(Mediator.PROJECT_BEGIN); // 之后,程序员工作,随后测试员工作 } }
由于上述代码输出带有随机性,输出可能不完全一致:
架构师收到:0 架构师开始设计,程序设计工作完成! 程序员收到:1 研发人员进行开发...开发完成! 架构师收到:2 架构师开始设计,程序设计工作完成! 程序员收到:1 研发人员进行开发...开发完成! 测试人员正在测试...测试完成!