中介者模式(行为型模式)
模式概述
中介者模式是一种行为设计模式,它能减少对象之间混乱无序的依赖关系,因为它会限制对象之间的直接交互,而迫使它们通过一个中介者对象来进行合作。
问题
一个建设中的小城镇正在飞速地发展着。过去的乡间路口如今车水马龙,人流涌动。由于每个人都急着赶路,导致这里竟然经常会发生交通拥堵。
每当这个时候,总有热心的居民或者司机站出来协调车流,慢慢使交通恢复正常但这种方式完全依赖于好人好事,如果遇不到这样热心肠的人,那就得一直堵着吗?
方案
中介者模式建议停止组件之间的直接交流,这些组件必须通过特殊的中介对象实现交流。
通过中介者对象重定向调用行为,以间接的方式进行合作。
最终,组件仅依赖于一个中介者类,无需与多个其他组件相耦合。

所以,中介者模式有时又被称为调停者模式。
结构

实现
Java
/**
* 组件接口
*
*/
public interface Component {
void setMediator(Mediator mediator);
String getName();
}
/**
* 添加按钮
*
*/
public class AddButton extends JButton implements Component {
private Mediator mediator;
public AddButton() {
super("Add");
}
@Override
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
@Override
protected void fireActionPerformed(ActionEvent actionEvent) {
mediator.addNewNote(new Note());
}
@Override
public String getName() {
return "AddButton";
}
}
/**
* 删除按钮
*
*/
public class DeleteButton extends JButton implements Component {
private Mediator mediator;
public DeleteButton() {
super("Del");
}
@Override
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
@Override
protected void fireActionPerformed(ActionEvent actionEvent) {
mediator.deleteNote();
}
@Override
public String getName() {
return "DelButton";
}
}
/**
* 中介者接口
*
*/
public interface Mediator {
void addNewNote(Note note);
void deleteNote();
}
/**
* 具体中介者
*
*/
public class Editor implements Mediator {
private AddButton add;
private DeleteButton del;
@Override
public void registerComponent(Component component) {
component.setMediator(this);
switch (component.getName()) {
case "AddButton":
add = (AddButton)component;
break;
case "DelButton":
del = (DeleteButton)component;
break;
}
}
@Override
public void addNewNote(Note note) {
System.out.println("添加笔记");
}
@Override
public void deleteNote() {
System.out.println("删除笔记");
}
@Override
public void createGUI() {
JPanel buttonPanel = new JPanel();
buttonPanel.add(add);
buttonPanel.add(del);
}
}
/**
* 客户端
*
*/
public class Client {
public static void main(String[] args) {
Mediator mediator = new Editor();
mediator.registerComponent(new AddButton());
mediator.registerComponent(new DeleteButton());
mediator.createGUI();
}
}
Go
package main
import "fmt"
/**
* 火车组件接口
*
*/
type Train interface {
arrive()
depart()
permitArrival()
}
/**
* 客运列车
*
*/
type PassengerTrain struct {
mediator Mediator
}
func (g *PassengerTrain) arrive() {
if !g.mediator.canArrive(g) {
fmt.Println("K9527: 进站受阻,等待中...")
return
}
fmt.Println("K9527: 到站")
}
func (g *PassengerTrain) depart() {
fmt.Println("K9527: 离站")
g.mediator.notifyAboutDeparture()
}
func (g *PassengerTrain) permitArrival() {
fmt.Println("K9527: 允许进站, 进站中...")
g.arrive()
}
/**
* 货运列车
*
*/
type FreightTrain struct {
mediator Mediator
}
func (g *FreightTrain) arrive() {
if !g.mediator.canArrive(g) {
fmt.Println("G9528: 进站受阻,等待中...")
return
}
fmt.Println("G9528: 到站")
}
func (g *FreightTrain) depart() {
fmt.Println("G9528: 离站")
g.mediator.notifyAboutDeparture()
}
func (g *FreightTrain) permitArrival() {
fmt.Println("G9528: 允许进站")
g.arrive()
}
/**
* 中介者接口
*
*/
type Mediator interface {
canArrive(Train) bool
notifyAboutDeparture()
}
/**
* 具体中介者
*
*/
type StationManager struct {
isPlatformFree bool
trainQueue []Train
}
func newStationManger() *StationManager {
return &StationManager{
isPlatformFree: true,
}
}
func (s *StationManager) canArrive(t Train) bool {
if s.isPlatformFree {
s.isPlatformFree = false
return true
}
s.trainQueue = append(s.trainQueue, t)
return false
}
func (s *StationManager) notifyAboutDeparture() {
if !s.isPlatformFree {
s.isPlatformFree = true
}
if len(s.trainQueue) > 0 {
firstTrainInQueue := s.trainQueue[0]
s.trainQueue = s.trainQueue[1:]
firstTrainInQueue.permitArrival()
}
}
/**
* 客户端
*
*/
func main() {
stationManager := newStationManger()
passengerTrain := &PassengerTrain{
mediator: stationManager,
}
freightTrain := &FreightTrain{
mediator: stationManager,
}
passengerTrain.arrive()
freightTrain.arrive()
passengerTrain.depart()
}
适用场景
当系统中对象之间存在复杂的引用关系,产生的相互依赖关系结构混乱且难以理解时,可以使用中介者模式。
当组件因过于依赖其他组件而无法在不同应用中复用时,可以使用中介者模式。
如果想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类时,可以使用中介者模式。
优缺点
中介者模式的优点。
将多个组件间的交流抽取到同一位置,使其更易于理解和维护,符合
单一职责原则
。无需修改实际组件就能增加新的中介者,符合
开闭原则
。可以减少应用中多个组件间的耦合并更方便地复用各个组件。
中介者模式的缺点。
- 中介者可能会演化成为上帝对象。
相关性
责任链模式
、命令模式
、中介者模式
和观察者模式
都用于处理请求发送者和接收者之间的不同连接方式。外观模式
和中介者模式
的职责类似,它们都尝试在大量紧密耦合的类中组织起合作。中介者模式
和观察者模式
之间的区别往往很难记住,这是因中介者模式
消除了一系列系统组件之间的相互依赖,因为这些组件只依赖于同一个中介者对象。而有些中介者模式
是通过观察者模式
实现的:中介者对象担当发布者的角色,其他组件则作为订阅者,当中介者以这种方式实现时,它看上去与观察者非常相似。
感谢支持
更多内容,请移步《超级个体》。