中介者模式:复杂交互的协调者

摘要

中介者模式(Mediator Pattern)是行为型设计模式中的"交互控制器",它通过封装一组对象之间的交互来降低对象之间的直接耦合。本文将深入解析中介者模式的核心概念、实现方式、应用场景及高级变体,通过丰富的Java代码示例展示如何构建集中式交互系统,并分析其与观察者模式、外观模式的区别与适用场景。

一、中介者模式核心思想

中介者模式的核心是集中控制对象交互,具有以下关键特征:

  1. 交互中心化:所有交互通过中介者进行
  2. 解耦对象:对象间不直接相互引用
  3. 简化通信:将多对多关系简化为一对多
  4. 控制集中:交互逻辑集中在中介者中

适用场景:

  • 对象间存在复杂网状引用关系
  • 对象间通信方式需要灵活变更
  • 需要集中管理对象间的交互规则
  • 对象需要重用但交互行为不可重用

二、中介者模式结构解析

UML类图示意

[Mediator] <|-- [ConcreteMediator]
[Colleague] <|-- [ConcreteColleagueA]
[Colleague] <|-- [ConcreteColleagueB]
[ConcreteColleagueA] --> [Mediator]
[ConcreteColleagueB] --> [Mediator]

核心组件角色

角色 职责 典型实现
Mediator 中介者接口 定义同事对象通信接口
ConcreteMediator 具体中介者 实现协调逻辑,维护同事引用
Colleague 同事类 知道中介者,通过中介者通信
ConcreteColleague 具体同事 实现业务功能,不直接引用其他同事

三、基础实现:聊天室案例

// 中介者接口
interface ChatMediator {
    void sendMessage(String msg, User user);
    void addUser(User user);
}

// 具体中介者:聊天室实现
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 msg, User user) {
        for (User u : this.users) {
            // 消息不发送给自己
            if (u != user) {
                u.receive(msg);
            }
        }
    }
}

// 同事类:用户
abstract class User {
    protected ChatMediator mediator;
    protected String name;
    
    public User(ChatMediator med, String name) {
        this.mediator = med;
        this.name = name;
    }
    
    public abstract void send(String msg);
    public abstract void receive(String msg);
}

// 具体同事类:普通用户
class BasicUser extends User {
    public BasicUser(ChatMediator med, String name) {
        super(med, name);
    }
    
    @Override
    public void send(String msg) {
        System.out.println(name + " sends: " + msg);
        mediator.sendMessage(msg, this);
    }
    
    @Override
    public void receive(String msg) {
        System.out.println(name + " receives: " + msg);
    }
}

// 具体同事类:VIP用户
class VIPUser extends User {
    public VIPUser(ChatMediator med, String name) {
        super(med, name);
    }
    
    @Override
    public void send(String msg) {
        System.out.println(name + " sends [VIP]: " + msg);
        mediator.sendMessage("[VIP] " + msg, this);
    }
    
    @Override
    public void receive(String msg) {
        System.out.println(name + " receives [VIP priority]: " + msg);
    }
}

// 客户端使用
public class ChatRoomDemo {
    public static void main(String[] args) {
        ChatMediator mediator = new ChatRoom();
        
        User john = new BasicUser(mediator, "John");
        User jane = new BasicUser(mediator, "Jane");
        User admin = new VIPUser(mediator, "Admin");
        
        mediator.addUser(john);
        mediator.addUser(jane);
        mediator.addUser(admin);
        
        john.send("Hi everyone");
        admin.send("Welcome to the chat!");
    }
}

四、高级应用:航空交通管制系统

1. 飞机与塔台交互

// 中介者接口
interface AirTrafficControl {
    void registerAircraft(Aircraft aircraft);
    void sendWarning(String message, Aircraft sender);
    void requestLandingClearance(Aircraft aircraft);
    void reportPosition(Aircraft aircraft, Position position);
}

// 具体中介者:控制塔
class ControlTower implements AirTrafficControl {
    private List<Aircraft> aircrafts = new ArrayList<>();
    private Map<Position, Aircraft> positionMap = new HashMap<>();
    
    @Override
    public void registerAircraft(Aircraft aircraft) {
        aircrafts.add(aircraft);
    }
    
    @Override
    public void sendWarning(String message, Aircraft sender) {
        aircrafts.stream()
            .filter(a -> a != sender)
            .forEach(a -> a.receiveWarning(message));
    }
    
    @Override
    public void requestLandingClearance(Aircraft aircraft) {
        boolean runwayClear = positionMap.values().stream()
            .noneMatch(a -> a.getStatus() == AircraftStatus.LANDING);
        
        if (runwayClear) {
            aircraft.receiveClearance(true);
            aircraft.setStatus(AircraftStatus.LANDING);
        } else {
            aircraft.receiveClearance(false);
            System.out.println("Runway occupied - please wait");
        }
    }
    
    @Override
    public void reportPosition(Aircraft aircraft, Position position) {
        positionMap.put(position, aircraft);
        checkForCollisions(aircraft, position);
    }
    
    private void checkForCollisions(Aircraft aircraft, Position position) {
        positionMap.forEach((pos, a) -> {
            if (a != aircraft && pos.distanceTo(position) < 5) {
                sendWarning("Collision alert with " + a.getId(), aircraft);
            }
        });
    }
}

// 同事类:飞机
class Aircraft {
    private AirTrafficControl atc;
    private String id;
    private AircraftStatus status;
    
    public Aircraft(AirTrafficControl atc, String id) {
        this.atc = atc;
        this.id = id;
        this.status = AircraftStatus.IN_FLIGHT;
        atc.registerAircraft(this);
    }
    
    public void sendWarning(String message) {
        atc.sendWarning(message, this);
    }
    
    public void requestLandingClearance() {
        atc.requestLandingClearance(this);
    }
    
    public void reportPosition(Position position) {
        atc.reportPosition(this, position);
    }
    
    public void receiveWarning(String message) {
        System.out.println(id + " received warning: " + message);
    }
    
    public void receiveClearance(boolean granted) {
        System.out.println(id + " landing clearance: " + (granted ? "GRANTED" : "DENIED"));
    }
    
    public String getId() {
        return id;
    }
    
    public AircraftStatus getStatus() {
        return status;
    }
    
    public void setStatus(AircraftStatus status) {
        this.status = status;
    }
}

// 辅助类
class Position {
    private double x, y, altitude;
    
    public Position(double x, double y, double altitude) {
        this.x = x;
        this.y = y;
        this.altitude = altitude;
    }
    
    public double distanceTo(Position other) {
        return Math.sqrt(
            Math.pow(x - other.x, 2) + 
            Math.pow(y - other.y, 2) +
            Math.pow(altitude - other.altitude, 2)
        );
    }
}

enum AircraftStatus {
    IN_FLIGHT, LANDING, ON_GROUND
}

// 使用示例
public class ATCSystem {
    public static void main(String[] args) {
        AirTrafficControl atc = new ControlTower();
        
        Aircraft flight1 = new Aircraft(atc, "FL123");
        Aircraft flight2 = new Aircraft(atc, "BA456");
        
        flight1.reportPosition(new Position(10, 20, 10000));
        flight2.reportPosition(new Position(12, 22, 10050));
        
        flight1.requestLandingClearance();
        flight2.requestLandingClearance();
    }
}

2. 微服务协调中介者

// 微服务中介者
class MicroservicesMediator {
    private Map<String, Microservice> services = new HashMap<>();
    private CircuitBreaker circuitBreaker = new CircuitBreaker();
    
    public void registerService(Microservice service) {
        services.put(service.getName(), service);
    }
    
    public Object forwardRequest(String serviceName, String request) {
        if (!circuitBreaker.isServiceAvailable(serviceName)) {
            return fallbackResponse(serviceName);
        }
        
        Microservice service = services.get(serviceName);
        if (service == null) {
            throw new IllegalArgumentException("Unknown service: " + serviceName);
        }
        
        try {
            Object response = service.handleRequest(request);
            circuitBreaker.recordSuccess(serviceName);
            return response;
        } catch (Exception e) {
            circuitBreaker.recordFailure(serviceName);
            return fallbackResponse(serviceName);
        }
    }
    
    private Object fallbackResponse(String serviceName) {
        // 返回缓存或默认响应
        return "Service " + serviceName + " is currently unavailable";
    }
    
    public void broadcastEvent(String eventName, Object eventData) {
        services.values().forEach(service -> {
            if (service.getSubscribedEvents().contains(eventName)) {
                service.handleEvent(eventName, eventData);
            }
        });
    }
}

// 微服务基类
abstract class Microservice {
    private MicroservicesMediator mediator;
    private String name;
    private Set<String> subscribedEvents = new HashSet<>();
    
    public Microservice(MicroservicesMediator mediator, String name) {
        this.mediator = mediator;
        this.name = name;
        mediator.registerService(this);
    }
    
    public String getName() {
        return name;
    }
    
    public Set<String> getSubscribedEvents() {
        return Collections.unmodifiableSet(subscribedEvents);
    }
    
    public void subscribeToEvent(String eventName) {
        subscribedEvents.add(eventName);
    }
    
    public Object callService(String serviceName, String request) {
        return mediator.forwardRequest(serviceName, request);
    }
    
    public void publishEvent(String eventName, Object eventData) {
        mediator.broadcastEvent(eventName, eventData);
    }
    
    public abstract Object handleRequest(String request);
    public abstract void handleEvent(String eventName, Object eventData);
}

// 断路器模式实现
class CircuitBreaker {
    private Map<String, ServiceState> serviceStates = new HashMap<>();
    private static final int FAILURE_THRESHOLD = 3;
    private static final long RETRY_TIMEOUT = 30000; // 30秒
    
    public boolean isServiceAvailable(String serviceName) {
        ServiceState state = serviceStates.get(serviceName);
        if (state == null) {
            return true;
        }
        
        if (state.status == Status.OPEN) {
            long now = System.currentTimeMillis();
            if (now - state.lastFailureTime > RETRY_TIMEOUT) {
                state.status = Status.HALF_OPEN;
                return true;
            }
            return false;
        }
        return true;
    }
    
    public void recordSuccess(String serviceName) {
        ServiceState state = serviceStates.get(serviceName);
        if (state != null && state.status == Status.HALF_OPEN) {
            state.status = Status.CLOSED;
            state.failureCount = 0;
        }
    }
    
    public void recordFailure(String serviceName) {
        ServiceState state = serviceStates.computeIfAbsent(
            serviceName, 
            k -> new ServiceState()
        );
        
        state.failureCount++;
        state.lastFailureTime = System.currentTimeMillis();
        
        if (state.failureCount >= FAILURE_THRESHOLD) {
            state.status = Status.OPEN;
        }
    }
    
    private static class ServiceState {
        Status status = Status.CLOSED;
        int failureCount = 0;
        long lastFailureTime = 0;
    }
    
    private enum Status {
        CLOSED, OPEN, HALF_OPEN
    }
}

// 使用示例
public class MicroservicesDemo {
    public static void main(String[] args) {
        MicroservicesMediator mediator = new MicroservicesMediator();
        
        Microservice orderService = new OrderService(mediator);
        Microservice paymentService = new PaymentService(mediator);
        
        // 服务间调用
        Object result = orderService.callService("PaymentService", "processPayment");
        System.out.println("Payment result: " + result);
        
        // 事件发布
        orderService.publishEvent("OrderCreated", "Order123");
    }
}

class OrderService extends Microservice {
    public OrderService(MicroservicesMediator mediator) {
        super(mediator, "OrderService");
        subscribeToEvent("PaymentProcessed");
    }
    
    @Override
    public Object handleRequest(String request) {
        return "Order processed: " + request;
    }
    
    @Override
    public void handleEvent(String eventName, Object eventData) {
        System.out.println("OrderService received event: " + eventName + " - " + eventData);
    }
}

class PaymentService extends Microservice {
    public PaymentService(MicroservicesMediator mediator) {
        super(mediator, "PaymentService");
        subscribeToEvent("OrderCreated");
    }
    
    @Override
    public Object handleRequest(String request) {
        return "Payment processed: " + request;
    }
    
    @Override
    public void handleEvent(String eventName, Object eventData) {
        System.out.println("PaymentService received event: " + eventName + " - " + eventData);
    }
}

五、中介者模式优缺点分析

优点:

优点 说明
降低耦合 对象间不直接相互引用
简化交互 将多对多关系简化为一对多
集中控制 交互规则集中管理
复用对象 对象可独立于交互方式复用
扩展灵活 新增交互规则不影响现有对象

缺点:

缺点 说明
复杂性转移 中介者可能变得过于复杂
单点故障 中介者故障影响整个系统
性能瓶颈 所有交互通过中介者可能影响性能
过度设计 简单系统使用中介者可能不必要

六、中介者模式与其他模式对比

中介者模式 vs 观察者模式

维度 中介者模式 观察者模式
通信方向 双向通信 单向通知
耦合度 对象知道中介者 观察者不知道被观察者
控制中心 集中控制交互 分布式事件处理
适用场景 复杂交互协调 状态变化通知

中介者模式 vs 外观模式

维度 中介者模式 外观模式
目的 协调对象间交互 简化子系统接口
参与者 同级对象间交互 为高层提供统一接口
知晓度 对象知道中介者 子系统不知道外观
复杂性 处理同级对象复杂交互 隐藏子系统复杂性

七、中介者模式最佳实践

1. 中介者与命令模式结合

// 命令接口
interface Command {
    void execute();
}

// 中介者扩展命令支持
class CommandMediator {
    private Map<String, Command> commands = new HashMap<>();
    private List<Command> history = new ArrayList<>();
    
    public void registerCommand(String name, Command command) {
        commands.put(name, command);
    }
    
    public void executeCommand(String name) {
        Command command = commands.get(name);
        if (command != null) {
            command.execute();
            history.add(command);
        }
    }
    
    public void undoLastCommand() {
        if (!history.isEmpty()) {
            Command command = history.remove(history.size() - 1);
            System.out.println("Undoing command: " + command.getClass().getSimpleName());
        }
    }
}

// 具体命令
class SaveCommand implements Command {
    private Document document;
    
    public SaveCommand(Document document) {
        this.document = document;
    }
    
    @Override
    public void execute() {
        document.save();
    }
}

// 使用示例
Document doc = new Document();
CommandMediator mediator = new CommandMediator();
mediator.registerCommand("save", new SaveCommand(doc));
mediator.executeCommand("save");

2. 中介者与状态模式结合

// 状态感知中介者
class StatefulMediator {
    private Map<Object, State> objectStates = new HashMap<>();
    
    public void setState(Object obj, State state) {
        objectStates.put(obj, state);
    }
    
    public void mediateInteraction(Object obj1, Object obj2) {
        State state1 = objectStates.get(obj1);
        State state2 = objectStates.get(obj2);
        
        if (state1 != null && state2 != null) {
            // 根据状态决定交互方式
            if (state1 == State.ACTIVE && state2 == State.ACTIVE) {
                System.out.println("Both objects active - standard interaction");
            } else if (state1 == State.BLOCKED || state2 == State.BLOCKED) {
                System.out.println("Blocked state detected - limited interaction");
            }
        }
    }
}

enum State {
    ACTIVE, INACTIVE, BLOCKED
}

3. 中介者与依赖注入

// 使用Spring框架的中介者
@Component
class SystemMediator {
    private final Map<String, SystemComponent> components = new HashMap<>();
    
    @Autowired
    public SystemMediator(List<SystemComponent> allComponents) {
        allComponents.forEach(component -> {
            components.put(component.getName(), component);
            component.setMediator(this);
        });
    }
    
    public void sendMessage(String componentName, String message) {
        SystemComponent component = components.get(componentName);
        if (component != null) {
            component.receiveMessage(message);
        }
    }
}

@Component
class NetworkComponent implements SystemComponent {
    private final String name = "Network";
    private SystemMediator mediator;
    
    public void setMediator(SystemMediator mediator) {
        this.mediator = mediator;
    }
    
    public void broadcast(String message) {
        mediator.sendMessage("All", message);
    }
    
    public void receiveMessage(String message) {
        System.out.println(name + " received: " + message);
    }
    
    public String getName() {
        return name;
    }
}

八、中介者模式在开源框架中的应用

Spring MVC中的DispatcherServlet

// DispatcherServlet作为HTTP请求的中介者
@Controller
public class UserController {
    @Autowired
    private UserService userService;
    
    @GetMapping("/users")
    public String listUsers(Model model) {
        model.addAttribute("users", userService.findAll());
        return "users/list";
    }
}

// DispatcherServlet协调Controller、ViewResolver等组件

Java Message Service (JMS)

// JMS作为消息中介者
ConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");
Connection connection = factory.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

Queue queue = session.createQueue("Orders");
MessageProducer producer = session.createProducer(queue);
MessageConsumer consumer = session.createConsumer(queue);

// 生产者发送消息
TextMessage message = session.createTextMessage("New order");
producer.send(message);

// 消费者接收消息
Message received = consumer.receive();
if (received instanceof TextMessage) {
    System.out.println("Received: " + ((TextMessage) received).getText());
}

九、高级应用:分布式中介者

1. 基于消息队列的分布式中介者

// 分布式中介者接口
interface DistributedMediator {
    void registerService(String serviceId, ServiceEndpoint endpoint);
    void sendCommand(String serviceId, Command command);
    void broadcastEvent(Event event);
}

// RabbitMQ实现
class RabbitMQMediator implements DistributedMediator {
    private final ConnectionFactory factory;
    private final Map<String, String> serviceQueues = new ConcurrentHashMap<>();
    
    public RabbitMQMediator(String host) {
        this.factory = new ConnectionFactory();
        this.factory.setHost(host);
    }
    
    @Override
    public void registerService(String serviceId, ServiceEndpoint endpoint) {
        try (Connection conn = factory.newConnection();
             Channel channel = conn.createChannel()) {
            
            String queueName = "service." + serviceId;
            channel.queueDeclare(queueName, false, false, false, null);
            serviceQueues.put(serviceId, queueName);
            
            // 启动消费者线程
            new Thread(() -> consumeMessages(serviceId, endpoint)).start();
        } catch (Exception e) {
            throw new RuntimeException("Registration failed", e);
        }
    }
    
    private void consumeMessages(String serviceId, ServiceEndpoint endpoint) {
        try (Connection conn = factory.newConnection();
             Channel channel = conn.createChannel()) {
            
            String queueName = serviceQueues.get(serviceId);
            channel.basicConsume(queueName, true, (consumerTag, delivery) -> {
                Command command = deserializeCommand(delivery.getBody());
                endpoint.handleCommand(command);
            }, consumerTag -> {});
            
        } catch (Exception e) {
            System.err.println("Consumer error: " + e.getMessage());
        }
    }
    
    @Override
    public void sendCommand(String serviceId, Command command) {
        // 实现命令发送逻辑...
    }
    
    @Override
    public void broadcastEvent(Event event) {
        // 实现事件广播逻辑...
    }
}

2. 微服务API网关

// API网关作为微服务中介者
@RestController
@RequestMapping("/api")
public class ApiGateway {
    @Autowired
    private UserServiceClient userService;
    
    @Autowired
    private OrderServiceClient orderService;
    
    @GetMapping("/user/{userId}/orders")
    public ResponseEntity<List<Order>> getUserOrders(@PathVariable String userId) {
        // 验证用户存在
        User user = userService.getUser(userId);
        if (user == null) {
            return ResponseEntity.notFound().build();
        }
        
        // 获取用户订单
        List<Order> orders = orderService.getUserOrders(userId);
        return ResponseEntity.ok(orders);
    }
}

十、中介者模式未来发展趋势

新兴应用方向:

  1. 服务网格:服务间通信的中介层
  2. 事件驱动架构:复杂事件处理中介
  3. 物联网平台:设备间交互协调
  4. 区块链智能合约:合约间交互中介
  5. AI系统集成:协调多个AI模型交互

响应式中介者模式

// Reactor中的中介者实现
class ReactiveMediator {
    private final Map<String, Sink<String>> commandSinks = new ConcurrentHashMap<>();
    private final Flux<String> eventBus;
    
    public ReactiveMediator() {
        this.eventBus = Flux.<String>create(sink -> {
            // 全局事件订阅
        }).publish().autoConnect();
    }
    
    public void registerService(String serviceId) {
        Sinks.Many<String> sink = Sinks.many().unicast().onBackpressureBuffer();
        commandSinks.put(serviceId, sink.asFlux());
    }
    
    public Flux<String> getServiceCommands(String serviceId) {
        return commandSinks.getOrDefault(serviceId, Flux.empty());
    }
    
    public void sendCommand(String serviceId, String command) {
        Sinks.Many<String> sink = (Sinks.Many<String>) commandSinks.get(serviceId);
        if (sink != null) {
            sink.tryEmitNext(command);
        }
    }
    
    public void publishEvent(String event) {
        eventBus.subscribe(event);
    }
    
    public Flux<String> getEventStream() {
        return eventBus;
    }
}

总结

中介者模式是管理复杂对象交互的强有力工具,特别适合对象间存在多对多关系的场景。其核心价值体现在:

  1. 交互解耦:消除对象间的直接引用
  2. 集中管理:统一维护交互规则
  3. 简化关系:将网状结构转为星型结构
  4. 灵活扩展:新增交互不影响现有对象

现代应用关键点:

  • 合理划分职责:避免中介者承担过多责任
  • 性能考量:分布式环境下的延迟问题
  • 错误处理:健壮的中介错误恢复机制
  • 与模式组合:结合观察者、命令等模式增强功能
  • 分布式支持:适应微服务和云原生架构

中介者模式正在与响应式编程、服务网格等现代技术结合,演进出更强大的交互管理能力。掌握中介者模式的精髓,将帮助开发者构建出更加清晰、可维护的系统架构,特别是在复杂的分布式系统领域。