中介者模式(Mediator Pattern)详解

发布于:2025-05-09 ⋅ 阅读:(17) ⋅ 点赞:(0)

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. 中介者模式的工作原理

  1. 各个同事对象持有对中介者对象的引用
  2. 当一个同事对象需要与其他同事对象交互时,它通过中介者对象发送消息
  3. 中介者对象接收到消息后,决定将消息转发给哪些同事对象
  4. 其他同事对象接收到中介者对象转发的消息,并作出响应
  5. 整个交互过程中,各个同事对象只与中介者对象交互,而不直接与其他同事对象通信

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();
                

网站公告

今日签到

点亮在社区的每一天
去签到