设计模式实战:深入理解中介者模式
模式定义
中介者模式(Mediator Pattern)是行为型设计模式,通过中介对象封装一系列对象交互,使各对象不需要显式相互引用,从而降低耦合度。该模式如同交通指挥中心,协调多方交互关系。
核心思想
交互中心化:所有通信通过中介者进行
对象解耦:消除对象间的网状依赖
统一控制:集中管理交互规则
简化协议:定义清晰的通信接口
适用场景
对象间存在复杂网状引用关系
需要集中管理多方交互规则
跨系统通信需要中间协调
交互协议需要统一维护
模式结构
Mediator:中介者接口,定义通信方法
ConcreteMediator:具体中介实现,协调各对象
Colleague:交互对象基类
ConcreteColleague:具体交互对象
PHP实现示例:聊天室消息中介
<?php
// 中介者接口
interface ChatMediator {
public function sendMessage(string $msg, User $user);
public function addUser(User $user);
}
// 具体中介者:聊天室服务器
class ChatRoom implements ChatMediator {
private $users = [];
public function addUser(User $user) {
$this->users[$user->getName()] = $user;
}
public function sendMessage(string $msg, User $sender) {
foreach ($this->users as $name => $user) {
if ($user !== $sender) {
$user->receive($msg, $sender->getName());
}
}
}
}
// 用户基类
abstract class User {
protected $mediator;
protected $name;
public function __construct(ChatMediator $mediator, string $name) {
$this->mediator = $mediator;
$this->name = $name;
$mediator->addUser($this);
}
public function getName(): string {
return $this->name;
}
abstract public function send(string $msg);
abstract public function receive(string $msg, string $sender);
}
// 具体用户类型
class ChatUser extends User {
public function send(string $msg) {
echo "{$this->name} 发送消息: $msg\n";
$this->mediator->sendMessage($msg, $this);
}
public function receive(string $msg, string $sender) {
echo "{$this->name} 收到来自 {$sender} 的消息: $msg\n";
}
}
// 客户端使用
$chatRoom = new ChatRoom();
$user1 = new ChatUser($chatRoom, "Alice");
$user2 = new ChatUser($chatRoom, "Bob");
$user3 = new ChatUser($chatRoom, "Charlie");
$user1->send("大家中午吃什么?");
$user2->send("我打算吃披萨");
/* 输出:
Alice 发送消息: 大家中午吃什么?
Bob 收到来自 Alice 的消息: 大家中午吃什么?
Charlie 收到来自 Alice 的消息: 大家中午吃什么?
Bob 发送消息: 我打算吃披萨
Alice 收到来自 Bob 的消息: 我打算吃披萨
Charlie 收到来自 Bob 的消息: 我打算吃披萨
*/
Go实现示例:空中交通管制系统
package main
import (
"fmt"
"sync"
)
// 中介者接口
type AirTrafficControl interface {
RequestLanding(airplane *Airplane) bool
NotifyTakeoff(airplane *Airplane)
}
// 具体中介者:塔台
type ControlTower struct {
runwayInUse bool
waitQueue []*Airplane
mu sync.Mutex
}
func (t *ControlTower) RequestLanding(airplane *Airplane) bool {
t.mu.Lock()
defer t.mu.Unlock()
if !t.runwayInUse {
t.runwayInUse = true
fmt.Printf("塔台: %s 允许降落\n", airplane.Name)
return true
}
fmt.Printf("塔台: %s 请等待\n", airplane.Name)
t.waitQueue = append(t.waitQueue, airplane)
return false
}
func (t *ControlTower) NotifyTakeoff(airplane *Airplane) {
t.mu.Lock()
defer t.mu.Unlock()
fmt.Printf("塔台: %s 已起飞\n", airplane.Name)
t.runwayInUse = false
if len(t.waitQueue) > 0 {
next := t.waitQueue[0]
t.waitQueue = t.waitQueue[1:]
fmt.Printf("塔台: 通知 %s 可以降落\n", next.Name)
next.ReceiveLandingPermission()
}
}
// 交互对象:飞机
type Airplane struct {
Name string
mediator AirTrafficControl
}
func (a *Airplane) RequestLanding() {
if a.mediator.RequestLanding(a) {
fmt.Printf("%s 开始降落\n", a.Name)
}
}
func (a *Airplane) ReceiveLandingPermission() {
fmt.Printf("%s 收到降落许可\n", a.Name)
a.RequestLanding()
}
func (a *Airplane) Takeoff() {
fmt.Printf("%s 请求起飞\n", a.Name)
a.mediator.NotifyTakeoff(a)
}
func main() {
tower := &ControlTower{}
planes := []*Airplane{
{Name: "CA123", mediator: tower},
{Name: "UA456", mediator: tower},
{Name: "AA789", mediator: tower},
}
var wg sync.WaitGroup
wg.Add(3)
// 模拟飞机依次请求降落
go func() {
defer wg.Done()
planes[0].RequestLanding()
planes[0].Takeoff()
}()
go func() {
defer wg.Done()
planes[1].RequestLanding()
}()
go func() {
defer wg.Done()
planes[2].RequestLanding()
}()
wg.Wait()
}
/* 输出示例:
塔台: CA123 允许降落
CA123 开始降落
CA123 请求起飞
塔台: CA123 已起飞
塔台: 通知 UA456 可以降落
UA456 收到降落许可
塔台: UA456 允许降落
UA456 开始降落
塔台: UA456 请等待
塔台: AA789 请等待
*/
模式优缺点
✅ 优点:
减少对象间耦合
集中控制交互逻辑
简化对象协议
提升系统可维护性
❌ 缺点:
中介者可能成为上帝对象
增加系统复杂度
通信效率可能降低
中介者修改影响全局
不同语言实现差异
中介者模式VS其他模式
模式演进方向
分布式中介者
结合消息中间件实现跨进程协调智能路由
添加AI算法优化交互决策状态管理
引入状态模式管理中介者行为服务网格
构建基于中介模式的Service Mesh容错机制
实现中介者故障转移和冗余备份
最佳实践建议
职责明确
严格限定中介者的协调边界协议简化
定义清晰简洁的通信接口性能优化
对高频交互进行批处理优化日志追踪
添加完整的交互日志记录异常隔离
防止单个组件故障影响全局
总结
中介者模式通过引入协调中心,将复杂的网状交互转化为星型结构,有效降低系统耦合度。该模式在以下场景表现卓越:
多对象存在复杂交互关系
需要集中管理交互规则
系统需要统一通信协议
组件需要动态协调机制
PHP与Go的实现差异体现了不同语言的特性优势:
PHP通过类继承体系直观展现对象关系
Go利用并发原语实现高性能协调
实际应用中需注意:
避免中介者过度复杂化
合理划分协调边界
注意并发环境下的线程安全
结合具体场景选择同步/异步通信
掌握中介者模式的关键在于理解"中心化协调"的设计哲学,这种通过中间层简化复杂交互的思想,是构建大型分布式系统的重要基础。