目录
1. 中介者模式
1.1 定义、优缺点、适用场景
- 1. 中介者模式
- 1.1 定义、优缺点、适用场景
- 1.2 模式的结构与实现
定义:中介者模式(Mediator Pattern),用一个中介对象来封装一系列的对象交互。中介者使各个对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。中介者模式属于行为型模式
优点:
- 各个客户只需和中介进行交互,将网状结构分离为星型结构,进行了解耦。符合迪米特原则
- 可以很方便的增加新的客户类,维护性和拓展性好
缺点:中介者承担了较多的责任,变得过于复杂,一旦中介者出现了问题,整个系统就会受到影响
适用场景:
- MVC模式,C(Controller控制器)是M(Model模型)和V(View视图)的中介者,在前后端交互时起到了中间人的作用
- 系统中对象之间存在复杂的引用关系,系统结构混乱且难以理解时,就可以用中介者模式解决
- 一个对象由于引用了其他很多对象并且直接和这些对象通信,导致难以复用该对象时,就可以用中介者模式解决
- 需要通过一个中间类来封装多个类中的行为,但又不想生成太多的子类
结构:
- 抽象客户类(Customer):定义客户类的抽象类,保存中介者对象,实现客户类的公共方法
- 具体客户类(ConcreteCustomer):实现抽象客户类。每个客户只知道自己的行为,而不了解其它客户类的行为,需要通过中介者间接完成具体客户类之间的通信交互
- 抽象中介者(Mediator):定义了客户对象到中介者对象的接口
- 中介者对象(ConcreteMediator):实现抽象方法, 他需要知道所有的具体的客户类, 即以一个HashMap来管理。并接收某个客户的消息,完成相应的任务
实现: 智能家居项目:早上闹钟响起的时候,窗帘自动打开;之后我们开灯,闹钟自动关闭。所有的家电控制都经中央处理系统进行控制,而不是家电之间相互控制
import java.util.HashMap;
public class MediatorTest {
public static void main(String[] args) {
// 创建一个中介者对象
Mediator mediator = new CentralMediator();
// 创建各个Customer对象并且加入到CentralMediator对象的HashMap中
Alarm alarm = new Alarm(mediator, "alarm");
Curtain curtain = new Curtain(mediator, "curtain");
Lamp lamp = new Lamp(mediator, "lamp");
// 闹钟响了,会自动打开窗帘
alarm.openAlarm();
// 灯开了,会自动关闭闹钟
lamp.openLamp();
}
}
// 抽象客户类
abstract class Customer {
protected Mediator mediator;
protected String name;
public Customer(Mediator mediator, String name) {
this.mediator = mediator;
this.name = name;
}
// 客户向中介发送消息,中介根据客户的消息做处理
public abstract void sendMessage(String message);
}
// 具体的客户类-闹钟
class Alarm extends Customer {
public Alarm(Mediator mediator, String name) {
super(mediator, name);
// 创建Alarm对象时,将自身注册到中央处理系统的HashMap中
this.mediator.Register(this.name, this);
}
@Override
public void sendMessage(String message) {
// 发送的消息,由中央处理系统进行接收并处理
this.mediator.getMessage(this.name, message);
}
public void openAlarm() {
System.out.println("闹钟响了,开始向中央处理系统发送开启窗帘的消息");
this.sendMessage("开启窗帘");
}
public void closeAlarm() {
System.out.println("闹钟已关闭");
}
}
// 具体的客户类-窗帘
class Curtain extends Customer {
public Curtain(Mediator mediator, String name) {
super(mediator, name);
// 创建Curtain对象时,将自身注册到中央处理系统的HashMap中
this.mediator.Register(this.name, this);
}
@Override
public void sendMessage(String message) {
// 窗帘不控制其它家电,不用实现该方法
}
public void openCurtain() {
System.out.println("窗帘已打开");
}
}
// 具体的客户类-灯
class Lamp extends Customer {
public Lamp(Mediator mediator, String name) {
super(mediator, name);
// 创建Lamp对象时,将自身注册到中央处理系统的HashMap中
this.mediator.Register(this.name, this);
}
@Override
public void sendMessage(String message) {
// 发送的消息,由中央处理系统进行接收并处理
this.mediator.getMessage(this.name, message);
}
public void openLamp() {
System.out.println("灯已打开,开始向中央处理系统发送关闭闹钟的消息");
this.sendMessage("关闭闹钟");
}
}
// 抽象中介者
abstract class Mediator {
// 将中介者的客户注册到HashMap中
public abstract void Register(String customerName, Customer customer);
// 接收客户的消息, 并根据消息和其它客户交互
public abstract void getMessage(String customerName, String message);
}
// 具体的中介者-中央处理系统
class CentralMediator extends Mediator {
// 保存所有的家电对象
private HashMap customerMap;
// 保存所有的电器种类名称和电器名称
private HashMap nameMap;
public CentralMediator() {
this.customerMap = new HashMap();
this.nameMap = new HashMap();
}
@Override
public void Register(String customerName, Customer customer) {
this.customerMap.put(customerName, customer);
if (customer instanceof Alarm) {
this.nameMap.put("Alarm", customerName);
} else if (customer instanceof Curtain) {
this.nameMap.put("Curtain", customerName);
} else if (customer instanceof Lamp) {
this.nameMap.put("Lamp", customerName);
}
}
// 接收家电发送的消息,并做出相应的处理
@Override
public void getMessage(String customerName, String message) {
// 处理闹钟发出的消息
if (this.customerMap.get(customerName) instanceof Alarm) {
if (message == "开启窗帘") {
// 调用窗帘,进行窗帘的打开
((Curtain) this.customerMap.get(this.nameMap.get("Curtain"))).openCurtain();
}
} else if (this.customerMap.get(customerName) instanceof Lamp) {
if (message == "关闭闹钟") {
// 调用闹钟,进行闹钟的关闭
((Alarm) this.customerMap.get(this.nameMap.get("Alarm"))).closeAlarm();
}
}
}
}
运行程序,结果如下:
闹钟响了,开始向中央处理系统发送开启窗帘的消息
窗帘已打开
灯已打开,开始向中央处理系统发送关闭闹钟的消息
闹钟已关闭