某个工作日的早晨,小A发现楼栋电梯停运了。他打开物业小程序提交报修单,短短10分钟后,楼栋公告屏就亮起了提示:“电梯故障已受理,预计2小时内修复”。这看似简单的流程背后,隐藏着一个精密的协作系统:
物业中心在收到报修后同步触发:
维修完成时,系统继续联动:
这正是中介者模式的经典实践——物业中心如同交通指挥台,让居民、维修队、保安队等20多个相关方无需直接对接,所有协作通过统一的中控系统完成。这种设计带来的三大优势显而易见:
如果缺失这个智能中枢:
小A可能需要逐个联系维修队长电话、到保安亭填写巡逻申请、在业主群刷屏提醒保洁,甚至要手动记录维修时间以备后续投诉。更麻烦的是,当小区引入垃圾代收服务时,每个住户都要重新获取清洁公司的联系方式、服务协议和支付接口——这种链式依赖正是软件系统失控的前兆。
中介者模式的精妙之处,在于它用「中间层」重新定义了协作规则。就像现代物业管理系统逐步集成智能调度算法,优秀的中介者类也应该具备路由决策、异常熔断、负载均衡等能力,而这一切对参与者来说都是透明的。
中介者模式是一种行为型设计模式。其核心思想是通过引入一个中介者对象来协调多个对象之间的交互,从而避免这些对象之间的直接依赖关系。这种模式的核心价值在于降低系统的耦合度,将原本复杂的网状交互结构转化为相对简单的星型结构。
如下图所示,不存在中介者的时候:
这种结构下,每个节点都需要知道其他所有节点的信息,耦合度极高。如果要修改其中一个节点的交互逻辑,可能需要修改与之相连的多个节点的代码,维护和扩展的难度非常大。
而加入中介者之后:
无论节点数量如何增加,每个节点只需要维护一个对中介者的引用,节点之间的耦合度大大降低。
当需要修改某个节点的交互逻辑时,只需要在中介者中进行相应的修改,而不需要修改其他节点的代码。同时,如果要添加新的节点,只需要让新节点与中介者建立联系,而不会影响到其他已有的节点,系统的可维护性和扩展性得到了显著提升。这充分体现了中介者模式将复杂的网状交互简化为星型交互,从而降低耦合度的优点。
如下图所示:
说明:
notify
方法,用于接收同事类的事件并协调响应。colleagueA
到colleagueD
)。notify
方法,根据事件类型调度不同同事的响应。setColleagueX
方法关联具体同事类。sendMessage
方法:同事类通过此方法向中介者发送事件。handleEvent
抽象方法:由具体同事类实现业务逻辑。Colleague
,实现handleEvent
处理具体事件。dataA
、dataB
)和方法(如doSomethingA()
)。发送事件:
ConcreteColleagueA
调用sendMessage("event1")
,将事件传递给中介者。
中介者调度:
ConcreteMediator
收到事件后,根据逻辑调用ConcreteColleagueB.handleEvent("event1")
或其他同事类。
响应事件:
被调用的同事类(如ConcreteColleagueB
)执行自身业务逻辑(如修改dataB
)。
中介者模式通过引入一个中间协调对象(中介者),将原本多个对象之间直接的网状交互关系转化为对象与中介者之间的星型交互关系。各对象不再直接调用其他对象的方法,而是通过中介者统一传递请求和响应,中介者负责处理各对象间的逻辑调度与数据传递。这种设计减少了对象间的直接耦合,降低了系统复杂度,使功能扩展和维护更集中可控。
我们以引言中的例子编写示例代码。
C++实现
#include
#include
#include
#include
// 前置声明
class Mediator;
// 抽象同事类
class Colleague {
public:
virtual void setMediator(std::shared_ptr mediator) = 0;
virtual ~Colleague() = default;
};
// 抽象中介者
class Mediator {
public:
virtual void notify(const std::string& event, const std::string& sender) = 0;
virtual ~Mediator() = default;
};
// 具体同事类:维修服务
class MaintenanceService : public Colleague, public std::enable_shared_from_this {
public:
void setMediator(std::shared_ptr mediator) override {
this->mediator_ = mediator;
}
void performRepair() {
std::cout << "维修队开始处理电梯故障..." << std::endl;
mediator_->notify("REPAIR_STARTED", "Maintenance");
}
void completeRepair() {
std::cout << "维修队完成电梯修复工作" << std::endl;
mediator_->notify("REPAIR_COMPLETED", "Maintenance");
}
private:
std::shared_ptr mediator_;
};
// 具体同事类:安保服务
class SecurityTeam : public Colleague {
public:
void setMediator(std::shared_ptr mediator) override {
this->mediator_ = mediator;
}
void focusMonitoring() {
std::cout << "安保人员开始重点监控3栋电梯间" << std::endl;
}
void releaseMonitoring() {
std::cout << "安保人员解除重点监控状态" << std::endl;
}
private:
std::shared_ptr mediator_;
};
// 具体同事类:通知系统
class NotificationSystem : public Colleague {
public:
void setMediator(std::shared_ptr mediator) override {
this->mediator_ = mediator;
}
void sendProgress() {
std::cout << "系统推送:故障已受理(三端同步)" << std::endl;
}
void sendRecovery() {
std::cout << "系统推送:电梯已恢复运行(含检修报告)" << std::endl;
}
private:
std::shared_ptr mediator_;
};
// 具体中介者:物业中心
class PropertyManagementCenter : public Mediator {
public:
void addService(const std::shared_ptr& service) {
services_.push_back(service);
}
void notify(const std::string& event, const std::string& sender) override {
if (event == "REPORT_RECEIVED") {
std::cout << "\n=== 开始处理报修流程 ===" << std::endl;
maintenance_->performRepair();
security_->focusMonitoring();
notifications_->sendProgress();
}
else if (event == "REPAIR_COMPLETED") {
std::cout << "\n=== 开始后续处理流程 ===" << std::endl;
security_->releaseMonitoring();
notifications_->sendRecovery();
updateEquipmentRecords();
scheduleCleaning();
}
}
// 模拟其他系统接口
void updateEquipmentRecords() {
std::cout << "更新电梯设备维护档案" << std::endl;
}
void scheduleCleaning() {
std::cout << "生成电梯井道清洁工单" << std::endl;
}
// 组件注入
void setComponents(
std::shared_ptr maintenance,
std::shared_ptr security,
std::shared_ptr notifications) {
maintenance_ = maintenance;
security_ = security;
notifications_ = notifications;
}
private:
std::shared_ptr maintenance_;
std::shared_ptr security_;
std::shared_ptr notifications_;
std::vector> services_;
};
// 客户端使用
int main() {
// 创建中介者
auto mediator = std::make_shared();
// 创建各个服务组件
auto maintenance = std::make_shared();
auto security = std::make_shared();
auto notifications = std::make_shared();
// 组件注册到中介者
mediator->setComponents(maintenance, security, notifications);
maintenance->setMediator(mediator);
security->setMediator(mediator);
notifications->setMediator(mediator);
// 模拟用户报修事件
std::cout << "用户提交电梯报修申请..." << std::endl;
mediator->notify("REPORT_RECEIVED", "Resident");
// 模拟维修完成事件
std::cout << "\n维修队反馈维修完成..." << std::endl;
mediator->notify("REPAIR_COMPLETED", "Maintenance");
return 0;
}
代码说明:
Mediator
:抽象中介者接口,定义通知方法PropertyManagementCenter
:具体中介者,协调各组件交互Colleague
:抽象同事类,所有具体服务组件继承该接口新增服务只需继承Colleague并注册到中介者
交互逻辑集中在中介者,不影响现有组件
完整审计日志可通过中介者的notify方法统一记录
上述代码只是展现简单示例,可以注意到在中介者内部处理具体事件时,使用了
if else
语句,但是随着功能增多,代码会变得臃肿难以维护,这并不符合开闭原则。可以根据具体情况使用通过事件映射表、策略方法、工厂模式等方式对中介者进行优化。
Java实现
import java.util.ArrayList;
import java.util.List;
// 抽象同事接口
interface Colleague {
void setMediator(Mediator mediator);
}
// 抽象中介者接口
interface Mediator {
void notify(String event, String sender);
}
// 具体同事类:维修服务
class MaintenanceService implements Colleague {
private Mediator mediator;
@Override
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
public void performRepair() {
System.out.println("维修队开始处理电梯故障...");
mediator.notify("REPAIR_STARTED", "Maintenance");
}
public void completeRepair() {
System.out.println("维修队完成电梯修复工作");
mediator.notify("REPAIR_COMPLETED", "Maintenance");
}
}
// 具体同事类:安保服务
class SecurityTeam implements Colleague {
private Mediator mediator;
@Override
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
public void focusMonitoring() {
System.out.println("安保人员开始重点监控3栋电梯间");
}
public void releaseMonitoring() {
System.out.println("安保人员解除重点监控状态");
}
}
// 具体同事类:通知系统
class NotificationSystem implements Colleague {
private Mediator mediator;
@Override
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
public void sendProgress() {
System.out.println("系统推送:故障已受理(三端同步)");
}
public void sendRecovery() {
System.out.println("系统推送:电梯已恢复运行(含检修报告)");
}
}
// 具体中介者:物业中心
class PropertyManagementCenter implements Mediator {
private MaintenanceService maintenance;
private SecurityTeam security;
private NotificationSystem notifications;
private List services = new ArrayList<>();
public void setComponents(MaintenanceService maintenance,
SecurityTeam security,
NotificationSystem notifications) {
this.maintenance = maintenance;
this.security = security;
this.notifications = notifications;
}
@Override
public void notify(String event, String sender) {
if ("REPORT_RECEIVED".equals(event)) {
System.out.println("\n=== 开始处理报修流程 ===");
maintenance.performRepair();
security.focusMonitoring();
notifications.sendProgress();
} else if ("REPAIR_COMPLETED".equals(event)) {
System.out.println("\n=== 开始后续处理流程 ===");
security.releaseMonitoring();
notifications.sendRecovery();
updateEquipmentRecords();
scheduleCleaning();
}
}
private void updateEquipmentRecords() {
System.out.println("更新电梯设备维护档案");
}
private void scheduleCleaning() {
System.out.println("生成电梯井道清洁工单");
}
public void addService(Colleague service) {
services.add(service);
}
}
// 客户端使用
public class MediatorDemo {
public static void main(String[] args) {
// 创建中介者
PropertyManagementCenter mediator = new PropertyManagementCenter();
// 创建各个服务组件
MaintenanceService maintenance = new MaintenanceService();
SecurityTeam security = new SecurityTeam();
NotificationSystem notifications = new NotificationSystem();
// 组件注册到中介者
mediator.setComponents(maintenance, security, notifications);
maintenance.setMediator(mediator);
security.setMediator(mediator);
notifications.setMediator(mediator);
// 模拟用户报修事件
System.out.println("用户提交电梯报修申请...");
mediator.notify("REPORT_RECEIVED", "Resident");
// 模拟维修完成事件
System.out.println("\n维修队反馈维修完成...");
mediator.notify("REPAIR_COMPLETED", "Maintenance");
}
}
对比维度 | 中介者模式 | 代理模式 |
---|---|---|
相同点 | - 均引入中间层解耦系统:代理隔离客户端与目标对象,中介者隔离同事对象间的直接交互。 - 均属于设计模式中的中间件思想,优化系统结构。 | |
核心目的 | 减少多个对象间的耦合,集中协调复杂交互关系(行为型模式) | 控制对单个对象的访问,增强或限制原对象的功能(结构型模式) |
对象间关系 | 多对多:中介者管理多个同事对象,双向通信 | 一对一:代理对象仅代表一个目标对象,单向访问(客户端→代理→目标) |
职责与功能 | 封装对象交互逻辑,实现复杂业务协调(如聊天室消息转发、系统模块解耦) | 提供访问控制、延迟加载、权限验证等附加功能(如远程代理、安全代理) |
设计原则 | 迪米特法则(减少对象间直接依赖) | 单一职责原则(分离访问控制与核心逻辑) |
适用场景 | 对象间交互复杂且需集中管理(如GUI组件通信、多玩家游戏协作) | 需间接访问或增强目标对象(如网络代理、缓存代理、权限代理) |
结构特点 | 包含中介者接口和多个同事类,中介者持有所有同事引用 | 代理类与目标类实现同一接口,客户端仅依赖代理 |
代码复杂度 | 中介者可能承担过多职责,导致类臃肿 | 代理类通常轻量,仅扩展特定功能 |
典型场景示例:
使用中介者模式时,需要关注以下几个方面的注意事项:
中介者模式适用于多种存在复杂交互关系的场景,如以下几类: