文章目录
1. 中介者模式概述
1.1 定义
中介者模式是一种行为型设计模式,它通过一个中介对象来封装一系列对象之间的交互。中介者使各个对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
1.2 基本思想
中介者模式的核心思想是:
- 将对象间的复杂交互关系转换为星形结构
- 对象之间不再直接通信,而是通过中介者对象协调完成
- 减少了对象间的相互依赖,降低了系统的耦合度
2. 中介者模式的结构
中介者模式包含以下角色:
- 抽象中介者(Mediator):定义了同事对象到中介者对象的接口
- 具体中介者(ConcreteMediator):实现抽象中介者的方法,协调各个同事对象来实现协作行为
- 抽象同事类(Colleague):定义了同事类的接口,保存对中介者对象的引用
- 具体同事类(ConcreteColleague):实现抽象同事类的方法,每个具体同事类只知道自己的行为,而不了解其他同事类的情况
3. 中介者模式的UML类图
┌───────────────┐ ┌───────────────────┐
│ <<interface>> │ │ Colleague │
│ Mediator │◄────────├───────────────────┤
├───────────────┤ │ -mediator:Mediator│
│+notifyColleague()│ │ +setMediator() │
└───────┬───────┘ │ +send() │
│ └─────────┬─────────┘
│ │
│ │
┌───────▼───────┐ ┌───────────┴─────────────┐
│ConcreteMediator│ │ │
├───────────────┤ │ │
│-colleagues │ │ │
│+notifyColleague()│ │ │
└───────────────┘ ┌───▼───────────┐ ┌───────▼─────────┐
│ConcreteColleague1│ │ConcreteColleague2│
├─────────────────┤ ├─────────────────┤
│+send() │ │+send() │
│+receive() │ │+receive() │
└─────────────────┘ └─────────────────┘
4. 中介者模式的工作原理
- 各个同事对象持有对中介者对象的引用
- 当一个同事对象需要与其他同事对象交互时,它通过中介者对象发送消息
- 中介者对象接收到消息后,决定将消息转发给哪些同事对象
- 其他同事对象接收到中介者对象转发的消息,并作出响应
- 整个交互过程中,各个同事对象只与中介者对象交互,而不直接与其他同事对象通信
5. Java实现示例
5.1 基本实现示例
下面是一个简单的中介者模式实现示例,模拟用户之间通过聊天室(中介者)进行交流:
import java.util.ArrayList;
import java.util.List;
// 抽象中介者
interface ChatMediator {
void sendMessage(String message, User user);
void addUser(User user);
}
// 抽象同事类
abstract class User {
protected ChatMediator mediator;
protected String name;
public User(ChatMediator mediator, String name) {
this.mediator = mediator;
this.name = name;
}
public abstract void send(String message);
public abstract void receive(String message);
}
// 具体中介者
class ChatRoom implements ChatMediator {
private List<User> users;
public ChatRoom() {
this.users = new ArrayList<>();
}
@Override
public void addUser(User user) {
this.users.add(user);
}
@Override
public void sendMessage(String message, User user) {
// 将消息发送给除了发送者之外的所有用户
for (User u : users) {
if (u != user) {
u.receive(message);
}
}
}
}
// 具体同事类
class ChatUser extends User {
public ChatUser(ChatMediator mediator, String name) {
super(mediator, name);
}
@Override
public void send(String message) {
System.out.println(this.name + " 发送消息: " + message);
mediator.sendMessage(message, this);
}
@Override
public void receive(String message) {
System.out.println(this.name + " 收到消息: " + message);
}
}
// 客户端代码
public class MediatorPatternDemo {
public static void main(String[] args) {
ChatMediator chatRoom = new ChatRoom();
User user1 = new ChatUser(chatRoom, "张三");
User user2 = new ChatUser(chatRoom, "李四");
User user3 = new ChatUser(chatRoom, "王五");
chatRoom.addUser(user1);
chatRoom.addUser(user2);
chatRoom.addUser(user3);
user1.send("大家好!");
System.out.println("---------");
user2.send("张三你好!");
}
}
5.2 飞机空中交通控制示例
下面是一个模拟飞机着陆控制塔作为中介者协调多架飞机的例子:
import java.util.ArrayList;
import java.util.List;
// 抽象中介者
interface AirTrafficControlMediator {
void registerFlight(Flight flight);
void registerRunway(Runway runway);
boolean isRunwayAvailable();
void setRunwayStatus(boolean status);
void notifyFlightLanded();
}
// 抽象同事类
interface Command {
void execute();
}
// 抽象飞行器
abstract class Flight {
protected AirTrafficControlMediator mediator;
public Flight(AirTrafficControlMediator mediator) {
this.mediator = mediator;
}
public abstract void land();
}
// 机场跑道类
class Runway {
private AirTrafficControlMediator mediator;
public Runway(AirTrafficControlMediator mediator) {
this.mediator = mediator;
mediator.registerRunway(this);
}
public void setStatus(boolean status) {
mediator.setRunwayStatus(status);
}
}
// 具体中介者
class AirTrafficControlTower implements AirTrafficControlMediator {
private Flight flight;
private Runway runway;
private boolean runwayAvailable;
public AirTrafficControlTower() {
runwayAvailable = true;
}
@Override
public void registerFlight(Flight flight) {
this.flight = flight;
}
@Override
public void registerRunway(Runway runway) {
this.runway = runway;
}
@Override
public boolean isRunwayAvailable() {
return runwayAvailable;
}
@Override
public void setRunwayStatus(boolean status) {
runwayAvailable = status;
}
@Override
public void notifyFlightLanded() {
System.out.println("跑道现在可用");
setRunwayStatus(true);
}
}
// 具体飞行器:航班
class CommercialFlight extends Flight {
private String flightNumber;
public CommercialFlight(AirTrafficControlMediator mediator, String flightNumber) {
super(mediator);
this.flightNumber = flightNumber;
mediator.registerFlight(this);
}
@Override
public void land() {
if (mediator.isRunwayAvailable()) {
System.out.println("商业航班 " + flightNumber + " 成功着陆。");
mediator.setRunwayStatus(false);
// 模拟飞机着陆后离开跑道
new Thread(() -> {
try {
Thread.sleep(3000); // 假设飞机需要3秒离开跑道
mediator.notifyFlightLanded();
} catch (InterruptedException e) {
e.printStackTrace();