中介者模式如同一幅无形的画卷,细腻地编织着各个对象间错综复杂的交流,将混沌的线条渲染成和谐的画面。
一、飞机控制系统
场景假设:我们有一个飞机控制系统,其中包括飞机、塔台和地面服务。
class Airplane {
private ControlTower tower;
private GroundService groundService;
// Airplane 需要知道 ControlTower 和 GroundService
public Airplane(ControlTower tower, GroundService groundService) {
this.tower = tower;
this.groundService = groundService;
}
public void requestLanding() {
// 需要直接与 ControlTower 通信
tower.grantLandingPermission();
}
public void requestBaggageService() {
// 需要直接与 GroundService 通信
groundService.provideBaggageService();
}
}
class ControlTower {
// ...
}
class GroundService {
// ...
}
在上面的飞机控制系统中 Airplane 需要直接与 ControlTower 和 GroundService 通信。如果我们有更多的组件,并且它们都需要相互通信,那么代码将变得非常复杂,每个组件都需要知道其他所有组件。
二、中介者模式
中介者模式(Mediator Pattern)是一种行为型
设计模式,旨在减少对象之间的直接通信,而是通过一个中介对象来协调各对象之间的交互。它促进了对象之间的松耦合,使得对象之间的通信更加灵活、可复用。
在中介者模式中,通常会有一个中介者(Mediator)对象,它封装了对象之间的交互逻辑。对象之间不再直接相互引用和调用,而是通过向中介者发送消息来与其他对象通信。这种方式将复杂的交互逻辑集中管理,有助于简化对象之间的关系,提高系统的可维护性和扩展性。
三、中介者模式的核心组件
中介者模式主要包含以下几个核心组件:
- 中介者(Mediator):这是一个接口,它定义了各个组件(也称为同事)之间通信的协议。中介者知道所有的同事,并决定如何和何时与它们进行通信。
- 具体中介者(Concrete Mediator):这是实现中介者接口的类。具体中介者知道所有的同事,并实现了在同事之间进行通信的逻辑。
- 同事(Colleague):这些是需要相互通信的对象。每个同事都知道它的中介者,并且只与它的中介者通信,而不是直接与其他同事通信。
在这个类图中:
Mediator
是一个接口,定义了send
方法,用于在同事之间发送消息。ConcreteMediator
是Mediator
的一个具体实现。它维护了一个Colleague
对象的列表,并实现了addColleague
方法来添加新的同事。Colleague
是一个接口,定义了send
和receive
方法,用于发送和接收消息。ConcreteColleague
是Colleague
的一个具体实现。它有一个name
属性来标识自己,和一个mediator
属性来引用它的中介者。
四、运用中介者模式
场景假设:我们需要开发一个飞机控制系统,其中包括飞机、塔台和地面服务。但是飞机、塔台以及地面服务之间不直接通信,而是通过一个中介进行信息交换。
-
定义中介者接口:首先,我们需要定义一个中介者接口,该接口定义了各个组件(也称为同事)之间通信的协议。
// 中介者接口,定义了在同事之间发送消息的方法 interface Mediator { void send(String message, Component component); }
-
定义同事接口:我们需要定义一个同事接口,该接口定义了同事需要实现的方法。
// 同事接口,定义了发送和接收消息的方法 interface Component { void send(String message); void receive(String message); }
-
创建具体中介者:然后,我们创建一个具体的中介者类,该类实现了中介者接口。具体中介者知道所有的同事,并实现了在同事之间进行通信的逻辑。
// 具体中介者类,实现了中介者接口 class ConcreteMediator implements Mediator { // 维护一个同事对象的列表 private List<Component> components; public ConcreteMediator() { this.components = new ArrayList<>(); } // 添加同事到列表中 public void addComponent(Component component) { components.add(component); } // 发送消息给所有其他同事 @Override public void send(String message, Component originator) { for (Component component : components) { // 不给发送消息的同事发送消息 if (component != originator) { component.receive(message); } } } }
-
创建具体同事:然后,我们创建具体的同事类,这些类实现了同事接口。每个同事都知道它的中介者,并且只与它的中介者通信,而不是直接与其他同事通信。
// 具体同事类,实现了同事接口 class ConcreteComponent implements Component { // 同事的名字 private String name; // 同事知道它的中介者 private Mediator mediator; public ConcreteComponent(String name, Mediator mediator) { this.name = name; this.mediator = mediator; } // 发送消息 @Override public void send(String message) { System.out.println(this.name + " sends: " + message); mediator.send(message, this); } // 接收消息 @Override public void receive(String message) { System.out.println(this.name + " receives: " + message); } }
-
用中介者模式:最后,我们可以使用中介者模式来简化组件之间的通信。
// 使用中介者模式 public static void main(String[] args) { // 创建一个具体的中介者 Mediator mediator = new ConcreteMediator(); // 创建具体的同事 Component airplane = new ConcreteComponent("Airplane", mediator); Component controlTower = new ConcreteComponent("ControlTower", mediator); Component groundService = new ConcreteComponent("GroundService", mediator); // 将同事添加到中介者的列表中 mediator.addComponent(airplane); mediator.addComponent(controlTower); mediator.addComponent(groundService); // 同事通过中介者发送和接收消息 airplane.send("Requesting landing permission."); controlTower.send("Landing permission granted."); groundService.send("Ready for baggage service."); }
五、中介者模式的应用场景
中介者模式通常应用在以下几种场景中:
- 复杂的通信:当对象之间的通信变得非常复杂,以至于难以理解和维护时,可以使用中介者模式。中介者模式可以将复杂的通信过程简化为星型通信,每个对象只需要与中介者通信,而不需要直接与其他对象通信。
- 解耦对象:当希望解耦一组对象,使它们不直接相互引用时,可以使用中介者模式。通过引入中介者,每个对象都只需要知道中介者,而不需要知道其他对象。
- 动态的行为:当需要在运行时动态地改变对象之间的交互行为时,可以使用中介者模式。通过改变中介者来改变对象之间的交互行为。
以下是一些具体的应用场景:
- 图形用户界面(GUI):在复杂的 GUI 中,各种控件(如按钮、文本框、列表框等)之间可能需要进行复杂的通信。通过引入一个中介者,我们可以将这些控件解耦,使它们只需要与中介者通信。
- 聊天室:在聊天室中,每个用户都需要与其他所有用户通信。通过引入一个中介者(聊天服务器),我们可以将用户解耦,使每个用户只需要与中介者通信。
- 航空交通控制系统:在航空交通控制系统中,飞机、塔台和地面服务等都需要进行复杂的通信。通过引入一个中介者,我们可以将这些组件解耦,使它们只需要与中介者通信。
六、小结
中介者模式是一种强大而优雅的设计模式,能够有效地简化和管理复杂系统中对象之间的交互关系。通过合理运用中介者模式,我们可以提高代码的可读性、可维护性和扩展性,使系统设计更加优雅和灵活。