本文目录导读:

我来详细解释PHP中介者模式如何降低耦合,并通过实际例子来说明。
中介者模式的核心思想
中介者模式通过引入一个中介对象,让多个对象之间不再直接相互引用,而是通过中介者来间接通信,从而降低对象之间的耦合度。
实际案例:聊天室系统
让我们通过一个聊天室系统来演示中介者模式如何降低耦合:
未使用中介者模式(高耦合)
<?php
// 用户类(直接互相通信,高耦合)
class User {
private $name;
private $friends = [];
public function __construct($name) {
$this->name = $name;
}
// 添加好友(直接关联)
public function addFriend(User $friend) {
$this->friends[] = $friend;
}
// 直接发送消息给好友
public function sendMessage($message, $recipient) {
echo "{$this->name} 发送消息给 {$recipient->getName()}: {$message}\n";
$recipient->receiveMessage($message, $this);
}
// 接收消息
public function receiveMessage($message, User $sender) {
echo "{$this->name} 收到来自 {$sender->getName()} 的消息: {$message}\n";
}
public function getName() {
return $this->name;
}
// 广播消息给所有好友
public function broadcastMessage($message) {
foreach ($this->friends as $friend) {
$this->sendMessage($message, $friend);
}
}
}
// 使用示例 - 高耦合
$alice = new User('Alice');
$bob = new User('Bob');
$charlie = new User('Charlie');
// 每个人都需要手动维护好友列表
$alice->addFriend($bob);
$alice->addFriend($charlie);
$bob->addFriend($alice);
$charlie->addFriend($alice);
// 发送消息
$alice->sendMessage('Hello Bob!', $bob);
问题:每个用户都需要知道其他用户,修改通信逻辑很困难。
使用中介者模式(低耦合)
<?php
// 中介者接口
interface ChatMediator {
public function sendMessage($message, User $sender);
public function broadcastMessage($message, User $sender);
public function addUser(User $user);
}
// 具体中介者 - 聊天室
class ChatRoom implements ChatMediator {
private $users = [];
public function addUser(User $user) {
$this->users[$user->getName()] = $user;
echo "用户 {$user->getName()} 加入了聊天室\n";
}
// 发送消息给指定用户
public function sendMessage($message, User $sender) {
// 这里可以通过某些逻辑找出接收者
foreach ($this->users as $user) {
if ($user !== $sender && $this->shouldReceive($sender, $user, $message)) {
$user->receiveMessage($message, $sender);
}
}
}
// 广播消息给所有用户
public function broadcastMessage($message, User $sender) {
foreach ($this->users as $user) {
if ($user !== $sender) {
$user->receiveMessage($message, $sender);
}
}
}
// 判断用户是否应该接收消息(可以基于权限、屏蔽等)
private function shouldReceive(User $sender, User $receiver, $message) {
// 这里可以添加过滤逻辑
return true; // 默认接收
}
// 移除用户
public function removeUser(User $user) {
if (isset($this->users[$user->getName()])) {
unset($this->users[$user->getName()]);
echo "用户 {$user->getName()} 离开了聊天室\n";
}
}
}
// 用户类(通过中介者通信)
class User {
private $name;
private $chatMediator;
private $blockedUsers = [];
public function __construct($name, ChatMediator $chatMediator) {
$this->name = $name;
$this->chatMediator = $chatMediator;
}
// 发送消息(通过中介者)
public function sendMessage($message) {
echo "{$this->name} 发送消息: {$message}\n";
$this->chatMediator->broadcastMessage($message, $this);
}
// 发送私密消息(通过中介者)
public function sendPrivateMessage($message, User $recipient) {
echo "{$this->name} 发送私密消息给 {$recipient->getName()}: {$message}\n";
// 通过中介者发送,不直接调用接收者
$this->chatMediator->sendMessageWithRecipient($message, $this, $recipient);
}
// 接收消息
public function receiveMessage($message, User $sender) {
// 检查是否是屏蔽的用户
if (in_array($sender->getName(), $this->blockedUsers)) {
echo "{$this->name} 屏蔽了 {$sender->getName()} 的消息\n";
return;
}
echo "{$this->name} 收到来自 {$sender->getName()} 的消息: {$message}\n";
}
// 屏蔽用户
public function blockUser(User $user) {
$this->blockedUsers[] = $user->getName();
echo "{$this->name} 屏蔽了 {$user->getName()}\n";
}
public function getName() {
return $this->name;
}
}
// 升级中介者,支持私密消息和更多功能
interface AdvancedChatMediator extends ChatMediator {
public function sendMessageWithRecipient($message, User $sender, User $recipient);
}
class AdvancedChatRoom extends ChatRoom implements AdvancedChatMediator {
public function sendMessageWithRecipient($message, User $sender, User $recipient) {
// 检查发送者是否被接收者屏蔽
$recipient->receiveMessage($message, $sender);
}
}
// 使用示例 - 低耦合
$chatRoom = new AdvancedChatRoom();
$alice = new User('Alice', $chatRoom);
$bob = new User('Bob', $chatRoom);
$charlie = new User('Charlie', $chatRoom);
// 用户加入聊天室(通过中介者)
$chatRoom->addUser($alice);
$chatRoom->addUser($bob);
$chatRoom->addUser($charlie);
// 用户之间不需要直接引用,通过中介者通信
$alice->sendMessage('Hello everyone!');
echo "---\n";
$bob->sendPrivateMessage('Hi Alice, private message', $alice);
echo "---\n";
// 自定义规则
$charlie->blockUser($alice);
$alice->sendMessage('This message will not reach Charlie');
带状态管理的中介者
<?php
// 复杂的中介者 - 带状态管理
interface NotificationMediator {
public function notify(User $user, $event, $data = null);
public function registerHandler($event, callable $handler);
}
class NotificationCenter implements NotificationMediator {
private $handlers = [];
private $userStates = [];
public function registerHandler($event, callable $handler) {
$this->handlers[$event][] = $handler;
}
public function notify(User $user, $event, $data = null) {
// 记录用户状态
$this->userStates[$user->getName()]['last_event'] = $event;
$this->userStates[$user->getName()]['last_time'] = time();
// 执行所有注册的处理程序
if (isset($this->handlers[$event])) {
foreach ($this->handlers[$event] as $handler) {
$handler($user, $data);
}
}
}
// 获取用户状态
public function getUserState(User $user) {
return $this->userStates[$user->getName()] ?? null;
}
}
// 使用复杂中介者的示例
class SocialMediaApp {
private $mediator;
public function __construct() {
$this->mediator = new NotificationCenter();
$this->setupHandlers();
}
private function setupHandlers() {
// 注册登录事件处理
$this->mediator->registerHandler('login', function($user, $data) {
echo "欢迎回来,{$user->getName()}!\n";
});
// 注册发帖事件处理
$this->mediator->registerHandler('post_created', function($user, $data) {
echo "{$user->getName()} 发布了新帖子: {$data['title']}\n";
});
// 注册消息事件处理
$this->mediator->registerHandler('message', function($user, $data) {
echo "{$user->getName()} 收到消息: {$data['content']}\n";
});
}
public function userLogin(User $user) {
$this->mediator->notify($user, 'login');
}
public function createPost(User $user, $title, $content) {
$this->mediator->notify($user, 'post_created', [
'title' => $title,
'content' => $content
]);
}
public function sendMessage(User $from, User $to, $content) {
$this->mediator->notify($to, 'message', [
'from' => $from->getName(),
'content' => $content
]);
}
}
// 使用示例
$app = new SocialMediaApp();
$user1 = new User('Alice', $app->getMediator());
$user2 = new User('Bob', $app->getMediator());
$app->userLogin($user1);
$app->userLogin($user2);
$app->createPost($user1, 'PHP设计模式', '中介者模式详解...');
$app->sendMessage($user2, $user1, '你好,Alice!');
中介者模式的优点
降低耦合度
// 用户之间不需要知道对方的存在
class User {
private $name;
private $mediator;
// 只需要依赖中介者
public function __construct($name, Mediator $mediator) {
$this->name = $name;
$this->mediator = $mediator;
}
// 发送消息通过中介者,不需要直接调用其他用户
public function send($message) {
$this->mediator->broadcast($message, $this);
}
}
易于扩展
// 新增功能只需修改中介者
class EnhancedChatRoom extends ChatRoom {
public function sendFile(User $from, User $to, $file) {
// 添加文件传输功能
}
public function createGroup($name, $members) {
// 添加群组功能
}
}
集中管理
// 所有通信逻辑集中在中介者中
class CentralMediator implements Mediator {
private $components = [];
public function notify(Component $sender, $event) {
// 统一的通信逻辑
// 可以在这里添加日志、权限检查、性能监控等
}
}
使用中介者模式的最佳实践
适用于复杂交互
// 适合:多个对象之间存在复杂的交互关系
class OrderProcessingMediator {
// 协调库存、支付、物流等多个系统
}
避免过度设计
// 不适合:简单的一对一通信
class SimpleCommunication {
// 直接调用足以,不需要中介者
}
注意性能
class OptimizedMediator {
// 缓存常用通信路径
private $cache = [];
// 异步处理非关键操作
private function asyncProcess(callable $callback) {
// 异步处理
}
}
中介者模式的核心价值:
- 解耦:对象之间不再直接引用,降低系统复杂度
- 集中控制:所有交互逻辑集中在中介者中,便于维护
- 灵活扩展:新功能的加入不需要修改原有的类
- 可重用性:中介者可以被多个系统复用
这种模式特别适合:
- 多对象之间存在复杂的交互
- 需要集中管理通信逻辑
- 系统经常需要改变交互规则
通过使用中介者模式,PHP应用可以保持模块间的低耦合,提高代码的可维护性和可扩展性。