Java中介模式对象间解耦通信

wen java案例 3

Java中介者模式:对象间解耦通信

中介者模式(Mediator Pattern)是一种行为设计模式,通过引入一个中介对象来封装一组对象之间的交互,从而减少对象间的直接耦合。

Java中介模式对象间解耦通信

核心概念

解决的问题:当多个对象之间存在复杂交互关系时,每个对象都需要知道其他对象的存在,形成网状结构,导致系统难以维护和扩展。

解决方案:将所有对象的交互逻辑集中到中介者中,形成星型结构。

结构图

┌─────────────┐     ┌─────────────┐
│   Colleague │     │   Mediator  │
│ (同事对象)  │◄────┤ (中介者接口)│
└──────┬──────┘     └──────┬──────┘
       │                   │
  ┌────┴────┐         ┌────┴────┐
  │ Concrete │         │ Concrete│
  │ Colleague│         │ Mediator│
  └──────────┘         └─────────┘
       ▲                    ▲
       │                    │
  ┌────┴────┐              │
  │Concrete │──────────────┘
  │Colleague│
  └─────────┘

经典实现示例:聊天室

// 1. 中介者接口
interface ChatMediator {
    void sendMessage(String message, User user);
    void addUser(User user);
}
// 2. 具体中介者
class ChatRoom implements ChatMediator {
    private List<User> users = new ArrayList<>();
    @Override
    public void addUser(User user) {
        users.add(user);
        System.out.println(user.getName() + " 加入了聊天室");
    }
    @Override
    public void sendMessage(String message, User sender) {
        for (User user : users) {
            // 消息不需要发送给自己
            if (user != sender) {
                user.receive(message, sender.getName());
            }
        }
    }
}
// 3. 同事对象抽象类
abstract class User {
    protected ChatMediator mediator;
    private String name;
    public User(ChatMediator mediator, String name) {
        this.mediator = mediator;
        this.name = name;
    }
    public String getName() { return name; }
    public abstract void send(String message);
    public abstract void receive(String message, String senderName);
}
// 4. 具体同事对象
class ChatUser extends User {
    public ChatUser(ChatMediator mediator, String name) {
        super(mediator, name);
    }
    @Override
    public void send(String message) {
        System.out.println(getName() + " 发送消息: " + message);
        mediator.sendMessage(message, this);
    }
    @Override
    public void receive(String message, String senderName) {
        System.out.println(getName() + " 收到来自 " + senderName + " 的消息: " + message);
    }
}
// 5. 使用示例
public class MediatorDemo {
    public static void main(String[] args) {
        ChatMediator chatRoom = new ChatRoom();
        User alice = new ChatUser(chatRoom, "Alice");
        User bob = new ChatUser(chatRoom, "Bob");
        User charlie = new ChatUser(chatRoom, "Charlie");
        chatRoom.addUser(alice);
        chatRoom.addUser(bob);
        chatRoom.addUser(charlie);
        alice.send("大家好!");
        System.out.println("---");
        bob.send("你好, Alice!");
    }
}

高级实现:航班控制系统

// 更复杂的例子:机场航班调度系统
interface AirportMediator {
    void requestLanding(Flight flight);
    void requestTakeoff(Flight flight);
    void notifyRunwayStatus(int runwayNumber, boolean isAvailable);
    void notifyWeatherChange(String weather);
}
class AirportControl implements AirportMediator {
    private Map<Integer, Boolean> runways = new HashMap<>();
    private List<Flight> flights = new ArrayList<>();
    private String currentWeather = "晴朗";
    public AirportControl() {
        runways.put(1, true);  // 跑道1可用
        runways.put(2, true);  // 跑道2可用
    }
    @Override
    public void requestLanding(Flight flight) {
        if (!"晴朗".equals(currentWeather)) {
            flight.deny("天气条件不适合降落");
            return;
        }
        for (Map.Entry<Integer, Boolean> entry : runways.entrySet()) {
            if (entry.getValue()) {
                runways.put(entry.getKey(), false);
                flight.approve("允许降落,使用跑道 " + entry.getKey());
                return;
            }
        }
        flight.deny("所有跑道繁忙,请等待");
    }
    @Override
    public void requestTakeoff(Flight flight) {
        if (!"晴朗".equals(currentWeather)) {
            flight.deny("天气条件不适合起飞");
            return;
        }
        for (Map.Entry<Integer, Boolean> entry : runways.entrySet()) {
            if (entry.getValue()) {
                runways.put(entry.getKey(), false);
                flight.approve("允许起飞,使用跑道 " + entry.getKey());
                // 模拟起飞后跑道释放
                new Timer().schedule(new TimerTask() {
                    @Override
                    public void run() {
                        runways.put(entry.getKey(), true);
                        notifyRunwayStatus(entry.getKey(), true);
                    }
                }, 5000);
                return;
            }
        }
        flight.deny("所有跑道繁忙,请等待");
    }
    @Override
    public void notifyRunwayStatus(int runwayNumber, boolean isAvailable) {
        System.out.println("跑道 " + runwayNumber + " quot; + (isAvailable ? "可用" : "不可用"));
    }
    @Override
    public void notifyWeatherChange(String weather) {
        this.currentWeather = weather;
        System.out.println("天气变化: " + weather);
        // 通知所有航班
        for (Flight flight : flights) {
            flight.weatherAlert(weather);
        }
    }
}
class Flight {
    private AirportMediator mediator;
    private String flightNumber;
    public Flight(AirportMediator mediator, String flightNumber) {
        this.mediator = mediator;
        this.flightNumber = flightNumber;
    }
    public void requestLanding() {
        mediator.requestLanding(this);
    }
    public void requestTakeoff() {
        mediator.requestTakeoff(this);
    }
    public void approve(String message) {
        System.out.println("航班 " + flightNumber + ": " + message + " ✓");
    }
    public void deny(String reason) {
        System.out.println("航班 " + flightNumber + ": 请求拒绝 - " + reason + " ✗");
    }
    public void weatherAlert(String weather) {
        System.out.println("航班 " + flightNumber + " 注意: 天气变为 " + weather);
    }
}

使用场景

  1. GUI组件通信:对话框中的按钮、文本框、列表等组件交互
  2. 消息系统:聊天应用、消息队列
  3. 游戏系统:玩家、NPC、环境之间的交互
  4. 工作流系统:任务分配、状态流转
  5. 物联网设备协调:智能家居设备联动

优缺点分析

优点

  • ✅ 减少对象间耦合,每个对象只需知道中介者
  • ✅ 将多对多交互简化为一对多交互
  • ✅ 集中控制交互逻辑,便于维护
  • ✅ 提高系统可扩展性

缺点

  • ❌ 中介者可能变得复杂庞大(上帝对象反模式)
  • ❌ 增加系统复杂度
  • ❌ 中介者故障会影响所有交互

与其他模式关系

  • 观察者模式:中介者可结合观察者模式实现事件通知
  • 命令模式:中介者可以管理命令的执行
  • 外观模式:中介者封装交互,外观封装子系统

最佳实践

  1. 控制中介者复杂度:当中介者变得庞大时,考虑拆分为多个专门中介者
  2. 组合使用事件驱动:结合观察者模式实现松耦合通信
  3. 使用接口抽象:定义清晰的中介者和同事接口
  4. 考虑使用消息队列:在分布式系统中,可用消息队列替代中介者

中介者模式特别适合处理复杂交互场景,能显著提高系统的可维护性和扩展性。

抱歉,评论功能暂时关闭!