Java设计模式之中介者模式详解
什么是中介者模式?
中介者模式(Mediator Pattern)是一种行为型设计模式,它用一个中介对象来封装一系列对象之间的交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
为什么使用中介者模式?
- 降低系统对象之间的耦合度
- 简化对象之间的交互
- 集中管理对象之间的交互
- 提高系统的可维护性
实现示例
1. 基本实现
// 中介者接口
public interface Mediator {
void sendMessage(String message, Colleague colleague);
}
// 抽象同事类
public abstract class Colleague {
protected Mediator mediator;
public Colleague(Mediator mediator) {
this.mediator = mediator;
}
public abstract void send(String message);
public abstract void receive(String message);
}
// 具体中介者
public class ConcreteMediator implements Mediator {
private ConcreteColleagueA colleagueA;
private ConcreteColleagueB colleagueB;
public void setColleagueA(ConcreteColleagueA colleague) {
this.colleagueA = colleague;
}
public void setColleagueB(ConcreteColleagueB colleague) {
this.colleagueB = colleague;
}
@Override
public void sendMessage(String message, Colleague colleague) {
if (colleague == colleagueA) {
colleagueB.receive(message);
} else {
colleagueA.receive(message);
}
}
}
// 具体同事类A
public class ConcreteColleagueA extends Colleague {
public ConcreteColleagueA(Mediator mediator) {
super(mediator);
}
@Override
public void send(String message) {
mediator.sendMessage(message, this);
}
@Override
public void receive(String message) {
System.out.println("同事A收到消息:" + message);
}
}
// 具体同事类B
public class ConcreteColleagueB extends Colleague {
public ConcreteColleagueB(Mediator mediator) {
super(mediator);
}
@Override
public void send(String message) {
mediator.sendMessage(message, this);
}
@Override
public void receive(String message) {
System.out.println("同事B收到消息:" + message);
}
}2. 聊天室示例
// 聊天室中介者
public interface ChatMediator {
void sendMessage(String message, User user);
void addUser(User user);
}
// 聊天室实现
public class ChatRoom implements ChatMediator {
private List<User> users = new ArrayList<>();
@Override
public void addUser(User user) {
users.add(user);
}
@Override
public void sendMessage(String message, User user) {
for (User u : users) {
if (u != user) {
u.receive(message);
}
}
}
}
// 用户抽象类
public 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);
}
// 普通用户
public class NormalUser extends User {
public NormalUser(ChatMediator mediator, String name) {
super(mediator, name);
}
@Override
public void send(String message) {
System.out.println(name + " 发送消息: " + message);
mediator.sendMessage(message, this);
}
@Override
public void receive(String message) {
System.out.println(name + " 收到消息: " + message);
}
}3. 航空管制示例
// 航空管制中介者
public interface AirTrafficControl {
void registerFlight(Flight flight);
void requestLanding(Flight flight);
void requestTakeoff(Flight flight);
}
// 航空管制塔
public class ControlTower implements AirTrafficControl {
private List<Flight> flights = new ArrayList<>();
private Queue<Flight> landingQueue = new LinkedList<>();
private Queue<Flight> takeoffQueue = new LinkedList<>();
@Override
public void registerFlight(Flight flight) {
flights.add(flight);
}
@Override
public void requestLanding(Flight flight) {
landingQueue.offer(flight);
processNextOperation();
}
@Override
public void requestTakeoff(Flight flight) {
takeoffQueue.offer(flight);
processNextOperation();
}
private void processNextOperation() {
if (!landingQueue.isEmpty()) {
Flight flight = landingQueue.poll();
System.out.println("允许" + flight.getFlightNumber() + "降落");
flight.land();
} else if (!takeoffQueue.isEmpty()) {
Flight flight = takeoffQueue.poll();
System.out.println("允许" + flight.getFlightNumber() + "起飞");
flight.takeoff();
}
}
}
// 航班类
public class Flight {
private String flightNumber;
private AirTrafficControl controlTower;
public Flight(String flightNumber, AirTrafficControl controlTower) {
this.flightNumber = flightNumber;
this.controlTower = controlTower;
controlTower.registerFlight(this);
}
public void requestLanding() {
System.out.println(flightNumber + "请求降落");
controlTower.requestLanding(this);
}
public void requestTakeoff() {
System.out.println(flightNumber + "请求起飞");
controlTower.requestTakeoff(this);
}
public void land() {
System.out.println(flightNumber + "已降落");
}
public void takeoff() {
System.out.println(flightNumber + "已起飞");
}
public String getFlightNumber() {
return flightNumber;
}
}4. 使用示例
public class Client {
public static void main(String[] args) {
// 基本示例
ConcreteMediator mediator = new ConcreteMediator();
ConcreteColleagueA colleagueA = new ConcreteColleagueA(mediator);
ConcreteColleagueB colleagueB = new ConcreteColleagueB(mediator);
mediator.setColleagueA(colleagueA);
mediator.setColleagueB(colleagueB);
colleagueA.send("你好,B!");
colleagueB.send("你好,A!");
// 聊天室示例
ChatMediator chatRoom = new ChatRoom();
User user1 = new NormalUser(chatRoom, "张三");
User user2 = new NormalUser(chatRoom, "李四");
User user3 = new NormalUser(chatRoom, "王五");
chatRoom.addUser(user1);
chatRoom.addUser(user2);
chatRoom.addUser(user3);
user1.send("大家好!");
// 航空管制示例
AirTrafficControl controlTower = new ControlTower();
Flight flight1 = new Flight("CA1234", controlTower);
Flight flight2 = new Flight("MU5678", controlTower);
flight1.requestLanding();
flight2.requestTakeoff();
}
}中介者模式的优点
- 减少了对象之间的耦合,使得对象易于独立地改变和复用
- 将对象间的交互封装到中介者中,使得交互逻辑集中化
- 简化了对象间的关系,将多对多转化为一对多
- 提高了系统的可维护性
中介者模式的缺点
- 中介者可能会变得过于复杂
- 中介者承担了较多的责任,可能会导致中介者类变得庞大
- 如果设计不当,中介者对象本身就可能产生过度耦合
适用场景
- 一组对象以定义良好但复杂的方式进行通信
- 一些对象之间的通信方式必须定制化
- 多个类相互耦合形成了网状结构
- 想要集中管理对象间的交互
与其他模式的关系
- 观察者模式:中介者模式通常用观察者模式实现
- 外观模式:中介者是对等的对象之间的交互,外观是单向的访问
- 命令模式:可以结合使用,中介者作为命令的接收者
总结
中介者模式是一种用于降低多个对象之间复杂关系的设计模式。它通过引入一个中介者对象,将系统中对象之间的直接交互转化为中介者对象协调的间接交互。这种模式在处理复杂的对象间通信时特别有用,如聊天室、航空管制等场景。
参考资料
- 《Design Patterns: Elements of Reusable Object-Oriented Software》
- 《Head First Design Patterns》
- Java API 文档
- Spring Framework 源码
希望这篇文章能帮助您更好地理解Java中的中介者模式。如果您有任何问题,欢迎在评论区讨论!
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 lucky845的博客!
评论