跳转到内容

Java中介者模式

来自代码酷

模板:Note

简介[编辑 | 编辑源代码]

中介者模式是一种行为型设计模式,用于减少多个对象或类之间的直接通信依赖,通过引入一个中介者对象来封装交互逻辑。该模式符合迪米特法则(Law of Demeter),即“最少知识原则”,能有效降低系统耦合度。

核心思想[编辑 | 编辑源代码]

  • 将网状交互结构转化为星型结构,中介者作为中心节点协调各方。
  • 对象间不直接引用,而是通过中介者转发请求。
  • 适用于对象间交互复杂但定义明确的场景(如GUI组件、聊天室系统)。

模式结构[编辑 | 编辑源代码]

classDiagram class Mediator { +mediate(Colleague): void } class ConcreteMediator { -colleague1: Colleague -colleague2: Colleague +mediate(Colleague): void } class Colleague { -mediator: Mediator +send(message: String): void +receive(message: String): void } class ConcreteColleague1 { +send(message: String): void +receive(message: String): void } class ConcreteColleague2 { +send(message: String): void +receive(message: String): void } Mediator <|-- ConcreteMediator Colleague <|-- ConcreteColleague1 Colleague <|-- ConcreteColleague2 Colleague o-- Mediator ConcreteMediator --> ConcreteColleague1 ConcreteMediator --> ConcreteColleague2

关键角色说明:

  • Mediator: 定义中介者接口,声明协调方法。
  • ConcreteMediator: 实现具体协调逻辑,维护同事对象引用。
  • Colleague: 定义同事类接口,持有中介者引用。
  • ConcreteColleague: 实现具体行为,通过中介者与其他同事通信。

代码示例[编辑 | 编辑源代码]

以下是一个简易聊天室实现,演示中介者模式如何管理用户消息传递:

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

// 2. 实现具体中介者
class ChatMediatorImpl implements ChatMediator {
    private List<User> users;

    public ChatMediatorImpl() {
        this.users = new ArrayList<>();
    }

    @Override
    public void sendMessage(String msg, User user) {
        for (User u : users) {
            if (u != user) { // 不发送给自己
                u.receive(msg);
            }
        }
    }

    @Override
    public void addUser(User user) {
        this.users.add(user);
    }
}

// 3. 定义同事类(User)
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);
}

// 4. 实现具体同事类
class UserImpl extends User {
    public UserImpl(ChatMediator med, String name) {
        super(med, name);
    }

    @Override
    public void send(String msg) {
        System.out.println(name + " 发送: " + msg);
        mediator.sendMessage(msg, this);
    }

    @Override
    public void receive(String msg) {
        System.out.println(name + " 收到: " + msg);
    }
}

// 5. 客户端使用
public class Main {
    public static void main(String[] args) {
        ChatMediator mediator = new ChatMediatorImpl();

        User user1 = new UserImpl(mediator, "Alice");
        User user2 = new UserImpl(mediator, "Bob");
        User user3 = new UserImpl(mediator, "Charlie");

        mediator.addUser(user1);
        mediator.addUser(user2);
        mediator.addUser(user3);

        user1.send("大家好!");
        user2.send("今天天气不错");
    }
}

输出结果:

Alice 发送: 大家好!
Bob 收到: 大家好!
Charlie 收到: 大家好!
Bob 发送: 今天天气不错
Alice 收到: 今天天气不错
Charlie 收到: 今天天气不错

实际应用场景[编辑 | 编辑源代码]

典型用例[编辑 | 编辑源代码]

1. GUI组件交互:如对话框中的按钮、输入框等组件通过中介者协调,而非直接互相调用。 2. 多玩家游戏系统:游戏角色间的战斗、交易等行为通过游戏服务器(中介者)转发。 3. 航空管制系统:飞机与塔台的关系,塔台作为中介者协调起飞/降落顺序。

模式优劣[编辑 | 编辑源代码]

优点 缺点
减少类间耦合 中介者可能变成“上帝对象”
简化对象协议 增加系统复杂度
便于维护交互逻辑 性能开销(间接调用)

进阶讨论[编辑 | 编辑源代码]

与观察者模式对比[编辑 | 编辑源代码]

  • 中介者模式:同事对象双向通信,中介者知晓所有参与者。
  • 观察者模式:单向通知,观察者不知道被观察者的存在。

性能优化技巧[编辑 | 编辑源代码]

  • 使用事件总线(如Guava EventBus)实现轻量级中介者。
  • 对高频交互场景,可采用异步消息队列(如Kafka)作为中介者。

页面模块:Message box/ambox.css没有内容。

总结[编辑 | 编辑源代码]

中介者模式通过集中控制交互逻辑,有效解决了对象间直接引用导致的耦合问题。在复杂交互系统中,该模式能显著提升代码可维护性,但需注意避免中介者职责膨胀。建议在以下场景采用:

  • 对象间存在大量复杂引用关系
  • 系统交互逻辑可能频繁变更
  • 需要清晰定义交互边界的模块化系统