在软件开发中,对象之间的交互设计直接影响系统的可扩展性、解耦性和可维护性。当多个对象需要进行事件通知、协调通信或请求执行时,可以使用观察者模式(Observer Pattern)、中介者模式(Mediator Pattern)和命令模式(Command Pattern)来优化代码结构。
这三种模式都属于行为型设计模式(Behavioral Design Patterns),但它们的目的、设计方式、适用场景都不同。本文将从事件驱动、对象交互、职责划分、解耦程度等方面进行对比,帮助你理解它们的区别,并在实际开发中选择合适的模式。
一、模式概览
模式 | 主要作用 | 适用场景 |
---|---|---|
观察者模式(Observer) | 建立一对多的依赖关系,使对象可以在状态变化时自动通知依赖它的对象 | 事件驱动系统,如 GUI 事件处理、消息订阅 |
中介者模式(Mediator) | 通过中介者对象来协调多个对象的交互,减少对象之间的直接依赖 | 多个对象需要进行复杂交互,如 GUI 组件管理、航班管制 |
命令模式(Command) | 将请求封装成对象,支持请求的存储、撤销、重做等操作 | 任务队列、宏命令、撤销重做功能(如编辑器撤销操作) |
核心区别
🔹 观察者模式 关注事件订阅与通知,适用于一对多的依赖关系。
🔹 中介者模式 关注减少对象间的直接依赖,适用于多对象协作的场景。
🔹 命令模式 关注封装请求,适用于请求的存储、执行与撤销。
二、事件驱动与对象交互方式对比
1. 观察者模式:基于事件的发布-订阅机制
观察者模式的核心思想是当被观察对象(Subject)状态发生变化时,所有观察者(Observers)都会收到通知。
🔹 适用于:GUI 事件、消息订阅/发布(如 RSS 订阅、股票价格更新)。
UML 结构
Subject(被观察者)
│
┌───┴──────────┐
ObserverA ObserverB(观察者)
2. 中介者模式:基于中介者的对象协调
中介者模式的核心思想是通过一个中介者(Mediator)协调多个对象(Colleague)的交互,而不是让对象之间直接通信。
🔹 适用于:GUI 组件通信(按钮、文本框、复选框)、聊天室、航班调度系统。
UML 结构
Mediator(中介者)
│
┌───┴──────────┐
ColleagueA ColleagueB(同事类)
3. 命令模式:基于请求封装的命令调用
命令模式的核心思想是将请求封装成对象(Command),并支持存储、撤销、排队执行等操作。
🔹 适用于:任务队列、撤销/重做(如文本编辑器)、远程请求处理。
UML 结构
Client(客户端)
│
┌───┴──────────┐
Invoker Command(命令)
│
┌───┴──────────┐
ConcreteCommand Receiver(接收者)
三、职责划分与解耦程度对比
模式 | 主要职责 | 解耦方式 |
---|---|---|
观察者模式 | 管理订阅者,自动通知事件变化 | 降低订阅者与发布者的耦合,但订阅者仍需依赖 Subject |
中介者模式 | 协调多个对象之间的通信 | 所有对象依赖 Mediator ,但不直接依赖彼此,降低耦合 |
命令模式 | 封装请求,支持撤销、重做 | 调用方与执行方解耦,但 Invoker 依赖 Command |
🔹 观察者模式 解耦了对象间的直接依赖,但观察者仍需依赖被观察对象的通知机制。
🔹 中介者模式 解耦了对象间的直接通信,但所有通信都通过 Mediator
进行,可能导致 Mediator
变得复杂。
🔹 命令模式 解耦了请求的发送者与执行者,支持存储和撤销操作。