中介者模式(Mediator pattern)用中介对象来集中相关对象之间复杂的沟通和控制方式。各同事对象之间不再直接引用,而是统一通过中介者交互,把网状依赖变成星形结构。
意图
集中相关对象之间复杂的沟通和控制方式。
类图
- Mediator:中介者,定义一个接口用于与各同事(Colleague)对象通信。
- Colleague:同事,相关对象。
原文图片丢失,据文字重绘。
classDiagram
class Colleague {
<<abstract>>
+onEvent(Mediator)
}
class Alarm
class CoffeePot
class Calender
class Sprinkler
class Mediator {
<<abstract>>
+doEvent(String)
}
class ConcreteMediator {
-Alarm alarm
-CoffeePot coffeePot
-Calender calender
-Sprinkler sprinkler
+doEvent(String)
}
Colleague <|-- Alarm
Colleague <|-- CoffeePot
Colleague <|-- Calender
Colleague <|-- Sprinkler
Mediator <|-- ConcreteMediator
ConcreteMediator o-- Alarm
ConcreteMediator o-- CoffeePot
ConcreteMediator o-- Calender
ConcreteMediator o-- Sprinkler
Colleague ..> Mediator : onEvent 通知
实现
Alarm(闹钟)、CoffeePot(咖啡壶)、Calendar(日历)、Sprinkler(喷头)是一组相关的对象,在某个对象的事件产生时需要去操作其它对象,形成了下面这种依赖结构(原文图片丢失,据文字重绘):
graph LR
Alarm --> CoffeePot
CoffeePot --> Calender
Calender --> Sprinkler
Sprinkler --> Alarm
Alarm --> Calender
CoffeePot --> Sprinkler
使用中介者模式可以将复杂的依赖结构变成星形结构(原文图片丢失,据文字重绘):
graph LR
Alarm --> Mediator
CoffeePot --> Mediator
Calender --> Mediator
Sprinkler --> Mediator
Mediator --> Alarm
Mediator --> CoffeePot
Mediator --> Calender
Mediator --> Sprinkler
同事类只依赖 Mediator 抽象,事件发生时把处理权交给中介者:
public abstract class Colleague {
public abstract void onEvent(Mediator mediator);
}
public class Alarm extends Colleague {
@Override
public void onEvent(Mediator mediator) {
mediator.doEvent("alarm");
}
public void doAlarm() {
System.out.println("doAlarm()");
}
}
public class CoffeePot extends Colleague {
@Override
public void onEvent(Mediator mediator) {
mediator.doEvent("coffeePot");
}
public void doCoffeePot() {
System.out.println("doCoffeePot()");
}
}
public class Calender extends Colleague {
@Override
public void onEvent(Mediator mediator) {
mediator.doEvent("calender");
}
public void doCalender() {
System.out.println("doCalender()");
}
}
public class Sprinkler extends Colleague {
@Override
public void onEvent(Mediator mediator) {
mediator.doEvent("sprinkler");
}
public void doSprinkler() {
System.out.println("doSprinkler()");
}
}
中介者集中处理各同事的事件:
public abstract class Mediator {
public abstract void doEvent(String eventType);
}
public class ConcreteMediator extends Mediator {
private Alarm alarm;
private CoffeePot coffeePot;
private Calender calender;
private Sprinkler sprinkler;
public ConcreteMediator(Alarm alarm, CoffeePot coffeePot, Calender calender, Sprinkler sprinkler) {
this.alarm = alarm;
this.coffeePot = coffeePot;
this.calender = calender;
this.sprinkler = sprinkler;
}
@Override
public void doEvent(String eventType) {
switch (eventType) {
case "alarm":
doAlarmEvent();
break;
case "coffeePot":
doCoffeePotEvent();
break;
case "calender":
doCalenderEvent();
break;
default:
doSprinklerEvent();
}
}
public void doAlarmEvent() {
alarm.doAlarm();
coffeePot.doCoffeePot();
calender.doCalender();
sprinkler.doSprinkler();
}
public void doCoffeePotEvent() {
// ...
}
public void doCalenderEvent() {
// ...
}
public void doSprinklerEvent() {
// ...
}
}
public class Client {
public static void main(String[] args) {
Alarm alarm = new Alarm();
CoffeePot coffeePot = new CoffeePot();
Calender calender = new Calender();
Sprinkler sprinkler = new Sprinkler();
Mediator mediator = new ConcreteMediator(alarm, coffeePot, calender, sprinkler);
// 闹钟事件到达,调用中介者就可以操作相关对象
alarm.onEvent(mediator);
}
}
输出:
doAlarm()
doCoffeePot()
doCalender()
doSprinkler()
JDK 中的应用
- All scheduleXXX() methods of java.util.Timer
- java.util.concurrent.Executor#execute()
- submit() and invokeXXX() methods of java.util.concurrent.ExecutorService
- scheduleXXX() methods of java.util.concurrent.ScheduledExecutorService
- java.lang.reflect.Method#invoke()
相关模式:与观察者的对比
中介者与观察者都在处理对象之间的通信:观察者通过发布-订阅,把主题的状态变化单向广播给多个观察者,是”一对多”的依赖;中介者则把同事对象之间的双向交互集中到中介对象中,把网状依赖变成星形。一对多的状态通知场景适合观察者,多个对象之间互相协调的场景适合中介者。
系列导航
- 上一篇:迭代器(Iterator)
- 下一篇:备忘录(Memento)