一、介绍
-
介者模式是一种行为型设计模式,它允许对象之间通过一个中介者对象进行通信,而不是直接相互引用。将多对多的关系转化为一对多的关系,对象之间不再直接相互通信,而是通过中介者进行通信,降低了对象之间的耦合度。
-
就好像在一个团队中,每个人都不直接与其他成员交流,而是通过一个团队领导来协调沟通。这样做可以有效减少成员之间的关联,提高系统的灵活性和可维护性
-
下面4个关键,同事对象的状态发生变化时,它会通知中介者,中介者可以根据需要向其他同事对象发送消息或者执行特定的操作
- 中介者接口:定义了中介者对象的接口,用于和各个同事类进行通信。
- 具体中介者:实现了中介者接口,负责协调、控制各个同事类的行为。
- 同事类:具体的对象类,需要和其他对象进行交互,但是通过中介者来实现
- 具体同事对象:实现同事接口,与其他同事对象进行通信时将请求转发给中介者
二、智能家居系统项目实现
-
需求:智能家居中各个设备之间的联动控制,如灯光、温度、安防等
-
Mediator
中介者接口定义控制设备的方法controlDevice
-
SmartHomeMediator
实现中介者接口,组合设备(同事类)有light灯光
、thermostat设备温度
、security安防类
,实现controlDevice
控制方法写逻辑、发送给各个设备对象的方法receiveMessage
-
Light 、Thermostat 、Security
同事类 - 具体设备类,主要定义接收来自中介者的消息方法receiveMessage
来控制开、关等设备方法 -
main
方法创建每个设备对象、以及中介者对象,中介者对象创建完,初始化引用每个设备对象。中介者对象自己方法controlDevice
发送消息给指定设备。
-
// 1.定义中介者接口
public interface Mediator {
// 控制设备的方法
void controlDevice(String device, String message);
}
// 2. 具体中介者类
public class SmartHomeMediator implements Mediator {
// 同事类 - 具体设备类
//灯光
private Light light;
//设备温度
private Thermostat thermostat;
//安防
private Security security;
public SmartHomeMediator(Light light, Thermostat thermostat, Security security) {
this.light = light;
this.thermostat = thermostat;
this.security = security;
}
@Override
public void controlDevice(String device, String message) {
// 根据设备名称分发消息给对应的设备
if (device.equalsIgnoreCase("light")) {
light.receiveMessage(message);
} else if (device.equalsIgnoreCase("thermostat")) {
thermostat.receiveMessage(message);
} else if (device.equalsIgnoreCase("security")) {
security.receiveMessage(message);
} else {
System.out.println("Device not found");
}
}
}
// 3. 同事类 - 具体设备类
public class Light {
// 打开灯光
public void turnOn() {
System.out.println("Light is on");
}
// 关闭灯光
public void turnOff() {
System.out.println("Light is off");
}
// 接收来自中介者的消息
public void receiveMessage(String message) {
// 根据消息内容执行相应动作
if (message.equalsIgnoreCase("turn on")) {
turnOn();
} else if (message.equalsIgnoreCase("turn off")) {
turnOff();
}
}
}
// 4. 同事类 - 具体设备类
public class Thermostat {
// 设置温度
public void setTemperature(int temperature) {
System.out.println("Thermostat set to " + temperature + " degrees");
}
// 接收来自中介者的消息
public void receiveMessage(String message) {
// 解析消息并执行相应动作
if (message.startsWith("set temperature")) {
int temperature = Integer.parseInt(message.split(" ")[2]);
setTemperature(temperature);
}
}
}
// 5. 同事类 - 具体设备类
public class Security {
// 启动安防系统
public void arm() {
System.out.println("Security system armed");
}
// 关闭安防系统
public void disarm() {
System.out.println("Security system disarmed");
}
// 接收来自中介者的消息
public void receiveMessage(String message) {
// 根据消息内容执行相应动作
if (message.equalsIgnoreCase("arm")) {
arm();
} else if (message.equalsIgnoreCase("disarm")) {
disarm();
}
}
}
public class Main {
public static void main(String[] args) {
// 创建中介者和各个设备
Light light = new Light();
Thermostat thermostat = new Thermostat();
Security security = new Security();
// 初始化智能家居中介者
Mediator smartHome = new SmartHomeMediator(light, thermostat, security);
// 控制各个设备
smartHome.controlDevice("light", "turn on");
smartHome.controlDevice("thermostat", "set temperature 22");
smartHome.controlDevice("security", "arm");
}
}
三、总结
1.优点
- 减少类之间的直接耦合,通过中介者模式,各个同事类不再直接依赖彼此,而是通过中介者来进行通信,从而降低了类之间的耦合度。
- 简化对象之间的交互,中介者模式提供了一个集中管理和协调对象之间交互的方式,使得对象之间的交互逻辑更加清晰和易于理解。
- 提高系统的灵活性,通过中介者模式,可以更容易地增加新的同事类或修改其行为,而不会影响到其他类。
2.缺点
- 中介者本身可能变得过于庞大,随着业务逻辑的增长,中介者可能会变得复杂,处理过多不同类的交互,导致中介者本身的维护困难。
- 增加了系统的复杂性,中介者模式引入了新的抽象层,会导致系统整体结构变得更加复杂。
3.使用经验
-
当需要管理多个对象之间的复杂交互时,考虑使用中介者模式,这可以帮助简化对象之间的通信。
-
避免滥用中介者模式,只有当对象之间的交互关系比较复杂且需要集中管理时才使用中介者模式,避免为了简单的交互关系而引入中介者。
-
注意中介者的职责,确保中介者的职责是清晰明确的,不要让中介者承担过多的责任,以免破坏单一职责原则。
4.Spring框架类似使用思想
- 常用类似中介者模式的设计来实现消息传递、事件处理、组件协作等功能
- Spring 提供了 ApplicationEvent 和 ApplicationListener 接口来实现事件的发布与订阅
- 这种机制就类似于中介者模式, ApplicationEvent 作为消息,ApplicationListener 充当中介者的角色,负责接收和处理事件消息。