PHP中绝大多数场景不需要手动实现中介者模式,因其Web请求生命周期短、协作关系扁平,强行使用反而增加复杂度;仅在多组件联动、WebSocket状态协调或CLI子命令事件共享等高耦合场景才需显式引入Mediator类。

中介者模式在 PHP 里到底该不该手写
直接说结论:PHP 中绝大多数场景不需要手动实现中介者模式。它不是语言级设施,而是为了解耦高度耦合的同事对象(Colleague)而存在的结构型模式;但在 PHP 的典型 Web 请求生命周期中,对象存活时间短、协作关系扁平(比如 Controller 调用 Service,Service 调用 Repository),根本达不到需要“中介者统一协调多个交互方”的复杂度。强行套用反而让代码更难读、更难测。
什么情况下真得用 Mediator 类
只有当出现以下任一情况时,才值得引入一个显式的 Mediator 类:
- 多个表单组件(如
DatePicker、TimeSelector、LocationAutocomplete)需要联动更新,且它们彼此不能直接引用对方(避免循环依赖或破坏封装) - WebSocket 长连接服务中,多个客户端实例需通过中心逻辑协调状态(例如聊天室中 A 发言触发 B 的提示音 + C 的未读计数 + D 的消息存档)
- 命令行工具里多个子命令(
ImportCommand、ValidateCommand、SyncCommand)需共享上下文并响应彼此事件,但又不能硬编码调用链
这时 Mediator 不是“为了设计模式而存在”,而是把原本散落在各处的 if-else 协调逻辑收拢到一处,降低变更成本。
Mediator 接口和同事类怎么写才不翻车
常见错误是让同事类(Colleague)持有 Mediator 实例并主动调用其方法,结果变成“同事控制中介者”,违背了中介者“隔离同事”的本意。正确做法是同事只通知事件,中介者决定如何响应:
// 同事基类:只发信号,不关心谁处理
abstract class Colleague
{
protected Mediator $mediator;
public function setMediator(Mediator $mediator): void
{
$this->mediator = $mediator;
}
// 关键:用事件名 + 数据,而非调用具体方法
protected function notify(string $event, array $data = []): void
{
$this->mediator->handle($event, $data, $this);
}
}
// 中介者接口:明确事件契约
interface Mediator
{
public function handle(string $event, array $data, Colleague $sender): void;
}
// 具体中介者:所有协调逻辑集中在此
class ChatRoomMediator implements Mediator
{
private array $colleagues = [];
public function register(Colleague $colleague): void
{
$this->colleagues[] = $colleague;
$colleague->setMediator($this);
}
public function handle(string $event, array $data, Colleague $sender): void
{
match($event) {
'message_sent' => $this->broadcastMessage($data, $sender),
'user_joined' => $this->notifyAll('user_status_changed', [...]),
default => throw new \LogicException("Unhandled event: {$event}"),
};
}
}
注意点:
- 同事类必须用
setMediator()注入,不能在构造时强制依赖——否则单元测试无法 mock -
handle()方法签名里保留$sender,否则无法判断“谁触发的”,联动逻辑会失效 - 不要在
Mediator里 new 具体同事类,否则破坏解耦;同事应由上层容器创建后注册进来
Laravel 或 Symfony 项目里别自己造轮子
框架本身已提供更轻量、更符合 PHP 习惯的替代方案:
- Laravel 的
Event+Listener机制就是中介者的函数式实现:OrderPlaced事件触发SendEmailListener、UpdateInventoryListener、LogActivityListener,完全解耦 - Symfony 的
EventDispatcher同理,且支持优先级、停止传播等控制能力 - 连 Laravel 的
Observers(如UserObserver)本质也是中介者变体:模型状态变化 → 触发外部响应
除非你在写一个不依赖框架的独立组件库,否则直接用框架事件系统,比手写 Mediator 类更易维护、更易调试、更少出错。
真正容易被忽略的是:中介者模式的价值不在“结构漂亮”,而在“当协作规则频繁变动时,你只需要改一个类”。如果现在连第一个协作规则都还没稳定,就先别急着建 Mediator 目录。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











