第二十一章:调停纷争,化解干戈——Mediator的中介艺术
第二十一章:调停纷争,化解干戈——Mediator的中介艺术
风云际会,中介者登场
在Visitor展示完他那精妙的访问艺术后,Mediator在人群中来回穿梭、忙于调停的和事佬走出。
"Visitor兄的操作分离确实精妙,"Mediator一边调解着两个正在争吵的对象,一边说道,“但在对象间通信复杂、相互依赖时,需要更加中心化的协调方式。当对象之间相互引用,形成网状结构时,系统会变得难以理解和维护。”
Mediator将两个争吵的对象分开,然后转向大家:“我的中介者模式,旨在用一个中介对象来封装一系列对象之间的交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互!”
架构老人眼中闪过赞许之色:“善!Mediator,就请你为大家展示这中介艺术的精妙所在。”
中介者模式的核心要义
Mediator面向众人,开始阐述他的武学真谛:
“在我的中介者模式中,主要包含两个核心角色:”
“Mediator(中介者):定义各个同事对象交互的接口。”
“ConcreteMediator(具体中介者):实现中介者接口,了解并维护各个同事对象,并协调各个同事对象之间的交互。”
“Colleague(同事类):每个同事类都知道它的中介者对象。每当它与另一个同事对象发生冲突时,就与它的中介者通信。”
"其精妙之处在于,"Mediator继续道,“我将网状的多对多关系转变为一对多的关系,将对象间的交互职责集中到中介者中,使得系统更易于理解和维护。”
C++实战:智能家居控制系统
"且让我以一个智能家居控制系统为例,展示中介者模式的实战应用。"Mediator说着,手中凝聚出一道道代码流光。
基础框架搭建
首先,Mediator定义了中介者和同事类的接口:
#include <iostream>
#include <vector>
#include <string>
#include <memory>
#include <algorithm>
#include <map>
#include <iomanip>
#include <sstream>
#include <chrono>
#include <thread>
#include <random>
#include <functional>// 前向声明
class SmartDevice;// 中介者接口
class HomeMediator {
public:virtual ~HomeMediator() = default;// 设备通信方法virtual void sendMessage(const std::string& message, SmartDevice* sender) = 0;virtual void sendCommand(const std::string& command, SmartDevice* sender, SmartDevice* receiver) = 0;virtual void broadcast(const std::string& message, SmartDevice* sender) = 0;// 设备管理virtual void registerDevice(SmartDevice* device) = 0;virtual void unregisterDevice(SmartDevice* device) = 0;// 场景管理virtual void activateScene(const std::string& sceneName) = 0;virtual void saveScene(const std::string& sceneName) = 0;// 系统信息virtual std::string getSystemStatus() const = 0;virtual std::string getMediatorName() const = 0;
};// 同事类接口 - 智能设备基类
class SmartDevice {
protected:HomeMediator* mediator_;std::string name_;std::string id_;bool isOnline_;std::string location_;public:SmartDevice(HomeMediator* mediator, const std::string& name, const std::string& id, const std::string& location = "未知位置"): mediator_(mediator), name_(name), id_(id), isOnline_(false), location_(location) {if (mediator_) {mediator_->registerDevice(this);}}virtual ~SmartDevice() = default;// 设备基本操作virtual void turnOn() = 0;virtual void turnOff() = 0;virtual void setValue(int value) = 0;// 消息处理virtual void receiveMessage(const std::string& message, SmartDevice* sender) = 0;virtual void receiveCommand(const std::string& command, SmartDevice* sender) = 0;// 设备信息std::string getName() const { return name_; }std::string getId() const { return id_; }std::string getLocation() const { return location_; }bool isOnline() const { return isOnline_; }void setOnline(bool online) { isOnline_ = online; std::cout << "🏠 设备 " << name_ << " " << (online ? "上线" : "下线") << std::endl;}void setLocation(const std::string& location) {location_ = location;}// 设备状态virtual std::string getStatus() const = 0;virtual std::string getDeviceType() const = 0;// 显示设备信息virtual void displayInfo() const {std::cout << "📱 设备: " << name_ << " [ID:" << id_ << "] " << "位置:" << location_ << " "<< (isOnline_ ? "🟢" : "🔴") << std::endl;}// 通过中介者发送消息void sendMessage(const std::string& message) {if (mediator_ && isOnline_) {mediator_->sendMessage(message, this);}}void sendCommand(const std::string& command, SmartDevice* receiver) {if (mediator_ && isOnline_) {mediator_->sendCommand(command, this, receiver);}}
};
具体中介者实现
Mediator展示了智能家居控制中心的具体实现:
// 具体中介者:智能家居控制中心
class SmartHomeCenter : public HomeMediator {
private:std::string centerName_;std::vector<SmartDevice*> devices_;std::map<std::string, std::map<std::string, std::string>> scenes_;std::vector<std::tuple<std::string, SmartDevice*, SmartDevice*, std::string>> messageHistory_;std::map<std::string, std::vector<std::function<void()>>> eventHandlers_;int totalMessages_;public:SmartHomeCenter(const std::string& name): centerName_(name), totalMessages_(0) {std::cout << "🏠 创建智能家居控制中心: " << centerName_ << std::endl;initializeEventHandlers();}void sendMessage(const std::string& message, SmartDevice* sender) override {if (!sender || !sender->isOnline()) {std::cout << "❌ 设备未上线,无法发送消息" << std::endl;return;}auto now = std::chrono::system_clock::now();messageHistory_.emplace_back("MESSAGE", sender, nullptr, message);totalMessages_++;// 广播消息给所有在线设备(除了发送者自己)std::cout << "📨 控制中心 " << centerName_ << " 广播消息..." << std::endl;for (auto* device : devices_) {if (device != sender && device->isOnline()) {device->receiveMessage(message, sender);}}// 显示消息日志std::time_t time = std::chrono::system_clock::to_time_t(now);std::cout << " 💭 " << sender->getName() << " 发送消息: " << message << " [时间: " << std::ctime(&time) << "]" << std::endl;// 触发消息事件triggerEvent("message_received", message);}void sendCommand(const std::string& command, SmartDevice* sender, SmartDevice* receiver) override {if (!sender || !sender->isOnline()) {std::cout << "❌ 发送设备未上线" << std::endl;return;}if (!receiver || !receiver->isOnline()) {std::cout << "❌ 接收设备未上线" << std::endl;return;}auto now = std::chrono::system_clock::now();messageHistory_.emplace_back("COMMAND", sender, receiver, command);totalMessages_++;std::cout << "🔄 " << sender->getName() << " 向 " << receiver->getName() << " 发送命令: " << command << std::endl;receiver->receiveCommand(command, sender);// 触发命令事件triggerEvent("command_sent", command);}void broadcast(const std::string& message, SmartDevice* sender) override {if (!sender || !sender->isOnline()) {std::cout << "❌ 设备未上线,无法广播" << std::endl;return;}auto now = std::chrono::system_clock::now();messageHistory_.emplace_back("BROADCAST", sender, nullptr, message);totalMessages_++;std::cout << "📢 " << sender->getName() << " 进行系统广播: " << message << std::endl;for (auto* device : devices_) {if (device->isOnline()) {device->receiveMessage("系统广播: " + message, sender);}}triggerEvent("broadcast_sent", message);}void registerDevice(SmartDevice* device) override {if (std::find(devices_.begin(), devices_.end(), device) == devices_.end()) {devices_.push_back(device);std::cout << "✅ 注册设备 " << device->getName() << " 到控制中心" << std::endl;triggerEvent("device_registered", device->getName());}}void unregisterDevice(SmartDevice* device) override {auto it = std::find(devices_.begin(), devices_.end(), device);if (it != devices_.end()) {devices_.erase(it);std::cout << "👋 从控制中心注销设备: " << device->getName() << std::endl;triggerEvent("device_unregistered", device->getName());}}void activateScene(const std::string& sceneName) override {auto it = scenes_.find(sceneName);if (it == scenes_.end()) {std::cout << "❌ 场景不存在: " << sceneName << std::endl;return;}std::cout << "🎭 激活场景: " << sceneName << std::endl;for (const auto& [deviceName, command] : it->second) {SmartDevice* device = findDeviceByName(deviceName);if (device && device->isOnline()) {std::cout << " 🎯 对设备 " << deviceName << " 执行: " << command << std::endl;// 在实际系统中,这里会解析命令并执行相应操作}}triggerEvent("scene_activated", sceneName);}void saveScene(const std::string& sceneName) override {std::cout << "💾 保存当前设备状态为场景: " << sceneName << std::endl;// 在实际系统中,这里会保存所有设备的当前状态scenes_[sceneName] = {}; // 简化实现triggerEvent("scene_saved", sceneName);}std::string getSystemStatus() const override {std::stringstream ss;ss << "🏠 系统状态 [" << centerName_ << "]" << std::endl;ss << " 设备总数: " << devices_.size() << " 个" << std::endl;int onlineCount = std::count_if(devices_.begin(), devices_.end(), [](SmartDevice* d) { return d->isOnline(); });ss << " 在线设备: " << onlineCount << " 个" << std::endl;ss << " 总消息数: " << totalMessages_ << " 条" << std::endl;ss << " 保存场景: " << scenes_.size() << " 个" << std::endl;return ss.str();}std::string getMediatorName() const override {return "智能家居控制中心: " + centerName_;}// 控制中心特有方法void showDeviceStatus() const {std::cout << "\n📊 设备状态报告:" << std::endl;std::cout << "================" << std::endl;for (const auto* device : devices_) {std::cout << " " << (device->isOnline() ? "🟢" : "🔴") << " "<< device->getName() << " - " << device->getStatus() << std::endl;}}void showMessageHistory() const {std::cout << "\n📜 消息历史 (" << messageHistory_.size() << " 条):" << std::endl;for (size_t i = 0; i < messageHistory_.size(); ++i) {const auto& [type, sender, receiver, content] = messageHistory_[i];std::string receiverName = receiver ? receiver->getName() : "所有人";std::cout << " " << (i + 1) << ". [" << type << "] " << sender->getName() << " → " << receiverName << ": " << content << std::endl;}}void addEventHandler(const std::string& eventType, std::function<void()> handler) {eventHandlers_[eventType].push_back(handler);}private:SmartDevice* findDeviceByName(const std::string& name) const {auto it = std::find_if(devices_.begin(), devices_.end(),[&name](SmartDevice* d) { return d->getName() == name; });return it != devices_.end() ? *it : nullptr;}void initializeEventHandlers() {// 初始化默认事件处理器eventHandlers_["device_registered"] = []() {std::cout << "🔔 新设备注册事件处理" << std::endl;};eventHandlers_["scene_activated"] = []() {std::cout << "🔔 场景激活事件处理" << std::endl;};}void triggerEvent(const std::string& eventType, const std::string& data) {auto it = eventHandlers_.find(eventType);if (it != eventHandlers_.end()) {for (const auto& handler : it->second) {handler();}}}
};
具体同事类实现
Mediator展示了各种智能设备的具体实现:
// 具体同事类:智能灯光
class SmartLight : public SmartDevice {
private:bool isOn_;int brightness_;std::string color_;std::vector<std::string> receivedMessages_;public:SmartLight(HomeMediator* mediator, const std::string& name, const std::string& id, const std::string& location = "客厅"): SmartDevice(mediator, name, id, location), isOn_(false), brightness_(50), color_("白色") {std::cout << "💡 创建智能灯光: " << name_ << std::endl;}void turnOn() override {isOn_ = true;std::cout << "💡 灯光 " << name_ << " 开启" << std::endl;sendMessage("灯光已开启");}void turnOff() override {isOn_ = false;std::cout << "💡 灯光 " << name_ << " 关闭" << std::endl;sendMessage("灯光已关闭");}void setValue(int value) override {brightness_ = std::max(0, std::min(100, value));std::cout << "💡 灯光 " << name_ << " 亮度设置为: " << brightness_ << "%" << std::endl;sendMessage("亮度设置为 " + std::to_string(brightness_) + "%");}void receiveMessage(const std::string& message, SmartDevice* sender) override {receivedMessages_.push_back(message);std::cout << "💡 灯光 " << name_ << " 收到来自 " << sender->getName() << " 的消息: " << message << std::endl;// 简单的自动响应逻辑if (message.find("晚安") != std::string::npos) {turnOff();setValue(10); // 设置为夜灯模式}}void receiveCommand(const std::string& command, SmartDevice* sender) override {std::cout << "💡 灯光 " << name_ << " 收到来自 " << sender->getName() << " 的命令: " << command << std::endl;if (command == "开启") {turnOn();} else if (command == "关闭") {turnOff();} else if (command.find("亮度") != std::string::npos) {// 解析亮度值try {int brightness = std::stoi(command.substr(command.find("亮度") + 2));setValue(brightness);} catch (...) {std::cout << "❌ 无效的亮度命令: " << command << std::endl;}}}std::string getStatus() const override {return std::string(isOn_ ? "开启" : "关闭") + " 亮度:" + std::to_string(brightness_) + "% 颜色:" + color_;}std::string getDeviceType() const override {return "智能灯光";}void displayInfo() const override {SmartDevice::displayInfo();std::cout << " 状态: " << getStatus() << std::endl;std::cout << " 收到消息: " << receivedMessages_.size() << " 条" << std::endl;}// 智能灯光特有方法void setColor(const std::string& color) {color_ = color;std::cout << "🎨 灯光 " << name_ << " 颜色设置为: " << color_ << std::endl;sendMessage("颜色设置为 " + color_);}void dim() {brightness_ = std::max(0, brightness_ - 10);std::cout << "💡 灯光 " << name_ << " 调暗至: " << brightness_ << "%" << std::endl;}
};// 具体同事类:智能空调
class SmartAirConditioner : public SmartDevice {
private:bool isOn_;int temperature_;std::string mode_; // 制冷/制热/送风int fanSpeed_; // 1-3档public:SmartAirConditioner(HomeMediator* mediator, const std::string& name,const std::string& id, const std::string& location = "客厅"): SmartDevice(mediator, name, id, location), isOn_(false),temperature_(25), mode_("制冷"), fanSpeed_(2) {std::cout << "❄️ 创建智能空调: " << name_ << std::endl;}void turnOn() override {isOn_ = true;std::cout << "❄️ 空调 " << name_ << " 开启" << std::endl;sendMessage("空调已开启");}void turnOff() override {isOn_ = false;std::cout << "❄️ 空调 " << name_ << " 关闭" << std::endl;sendMessage("空调已关闭");}void setValue(int value) override {temperature_ = std::max(16, std::min(30, value));std::cout << "❄️ 空调 " << name_ << " 温度设置为: " << temperature_ << "°C" << std::endl;sendMessage("温度设置为 " + std::to_string(temperature_) + "°C");}void receiveMessage(const std::string& message, SmartDevice* sender) override {std::cout << "❄️ 空调 " << name_ << " 收到来自 " << sender->getName() << " 的消息: " << message << std::endl;// 自动响应逻辑if (message.find("热") != std::string::npos) {setMode("制冷");setValue(22);sendMessage("已自动调整为制冷模式");} else if (message.find("冷") != std::string::npos) {setMode("制热");setValue(26);sendMessage("已自动调整为制热模式");}}void receiveCommand(const std::string& command, SmartDevice* sender) override {std::cout << "❄️ 空调 " << name_ << " 收到来自 " << sender->getName() << " 的命令: " << command << std::endl;if (command == "开启") {turnOn();} else if (command == "关闭") {turnOff();} else if (command.find("温度") != std::string::npos) {try {int temp = std::stoi(command.substr(command.find("温度") + 2));setValue(temp);} catch (...) {std::cout << "❌ 无效的温度命令: " << command << std::endl;}} else if (command.find("模式") != std::string::npos) {std::string mode = command.substr(command.find("模式") + 2);setMode(mode);}}std::string getStatus() const override {return std::string(isOn_ ? "开启" : "关闭") + " 温度:" + std::to_string(temperature_) + "°C 模式:" + mode_ + " 风速:" + std::to_string(fanSpeed_) + "档";}std::string getDeviceType() const override {return "智能空调";}void displayInfo() const override {SmartDevice::displayInfo();std::cout << " 状态: " << getStatus() << std::endl;}// 智能空调特有方法void setMode(const std::string& mode) {mode_ = mode;std::cout << "❄️ 空调 " << name_ << " 模式设置为: " << mode_ << std::endl;sendMessage("模式设置为 " + mode_);}void setFanSpeed(int speed) {fanSpeed_ = std::max(1, std::min(3, speed));std::cout << "❄️ 空调 " << name_ << " 风速设置为: " << fanSpeed_ << "档" << std::endl;sendMessage("风速设置为 " + std::to_string(fanSpeed_) + "档");}
};// 具体同事类:智能窗帘
class SmartCurtain : public SmartDevice {
private:bool isOpen_;int openPercentage_; // 0-100%std::string material_;public:SmartCurtain(HomeMediator* mediator, const std::string& name,const std::string& id, const std::string& location = "卧室"): SmartDevice(mediator, name, id, location), isOpen_(false),openPercentage_(0), material_("遮光布") {std::cout << "🪟 创建智能窗帘: " << name_ << std::endl;}void turnOn() override {open(100);}void turnOff() override {close();}void setValue(int value) override {openPercentage_ = std::max(0, std::min(100, value));isOpen_ = openPercentage_ > 0;std::cout << "🪟 窗帘 " << name_ << " 开合度设置为: " << openPercentage_ << "%" << std::endl;sendMessage("开合度设置为 " + std::to_string(openPercentage_) + "%");}void receiveMessage(const std::string& message, SmartDevice* sender) override {std::cout << "🪟 窗帘 " << name_ << " 收到来自 " << sender->getName() << " 的消息: " << message << std::endl;// 自动响应逻辑if (message.find("起床") != std::string::npos || message.find("早安") != std::string::npos) {open(100);sendMessage("已自动打开窗帘");} else if (message.find("睡觉") != std::string::npos || message.find("晚安") != std::string::npos) {close();sendMessage("已自动关闭窗帘");}}void receiveCommand(const std::string& command, SmartDevice* sender) override {std::cout << "🪟 窗帘 " << name_ << " 收到来自 " << sender->getName() << " 的命令: " << command << std::endl;if (command == "开启" || command == "打开") {open(100);} else if (command == "关闭") {close();} else if (command.find("开合") != std::string::npos) {try {int percentage = std::stoi(command.substr(command.find("开合") + 2));setValue(percentage);} catch (...) {std::cout << "❌ 无效的开合度命令: " << command << std::endl;}}}std::string getStatus() const override {return std::string(isOpen_ ? "开启" : "关闭") + " 开合度:" + std::to_string(openPercentage_) + "% 材质:" + material_;}std::string getDeviceType() const override {return "智能窗帘";}void displayInfo() const override {SmartDevice::displayInfo();std::cout << " 状态: " << getStatus() << std::endl;}// 智能窗帘特有方法void open(int percentage = 100) {setValue(percentage);std::cout << "🪟 窗帘 " << name_ << " 打开至 " << openPercentage_ << "%" << std::endl;}void close() {setValue(0);std::cout << "🪟 窗帘 " << name_ << " 完全关闭" << std::endl;}void setMaterial(const std::string& material) {material_ = material;std::cout << "🪟 窗帘 " << name_ << " 材质设置为: " << material_ << std::endl;}
};
UML 武功秘籍图
实战演练:高级家居系统
Mediator继续展示更复杂的中介者模式应用:
// 具体同事类:智能安防摄像头
class SecurityCamera : public SmartDevice {
private:bool isRecording_;std::string recordingQuality_;int motionSensitivity_;std::vector<std::string> detectedEvents_;public:SecurityCamera(HomeMediator* mediator, const std::string& name,const std::string& id, const std::string& location = "门口"): SmartDevice(mediator, name, id, location), isRecording_(false),recordingQuality_("1080p"), motionSensitivity_(5) {std::cout << "📹 创建安防摄像头: " << name_ << std::endl;}void turnOn() override {isRecording_ = true;std::cout << "📹 摄像头 " << name_ << " 开始录制" << std::endl;sendMessage("开始监控录制");}void turnOff() override {isRecording_ = false;std::cout << "📹 摄像头 " << name_ << " 停止录制" << std::endl;sendMessage("停止监控录制");}void setValue(int value) override {motionSensitivity_ = std::max(1, std::min(10, value));std::cout << "📹 摄像头 " << name_ << " 移动侦测灵敏度设置为: " << motionSensitivity_ << std::endl;sendMessage("移动侦测灵敏度设置为 " + std::to_string(motionSensitivity_));}void receiveMessage(const std::string& message, SmartDevice* sender) override {std::cout << "📹 摄像头 " << name_ << " 收到来自 " << sender->getName() << " 的消息: " << message << std::endl;}void receiveCommand(const std::string& command, SmartDevice* sender) override {std::cout << "📹 摄像头 " << name_ << " 收到来自 " << sender->getName() << " 的命令: " << command << std::endl;if (command == "开启" || command == "开始录制") {turnOn();} else if (command == "关闭" || command == "停止录制") {turnOff();} else if (command.find("灵敏度") != std::string::npos) {try {int sensitivity = std::stoi(command.substr(command.find("灵敏度") + 3));setValue(sensitivity);} catch (...) {std::cout << "❌ 无效的灵敏度命令: " << command << std::endl;}}}std::string getStatus() const override {return std::string(isRecording_ ? "录制中" : "待机") + " 画质:" + recordingQuality_ + " 灵敏度:" + std::to_string(motionSensitivity_);}std::string getDeviceType() const override {return "安防摄像头";}void displayInfo() const override {SmartDevice::displayInfo();std::cout << " 状态: " << getStatus() << std::endl;std::cout << " 检测事件: " << detectedEvents_.size() << " 个" << std::endl;}// 安防摄像头特有方法void detectMotion() {if (isRecording_ && isOnline_) {detectedEvents_.push_back("移动侦测事件");std::cout << "🚨 摄像头 " << name_ << " 检测到移动!" << std::endl;sendMessage("检测到移动,请检查");broadcast("检测到可疑移动,请注意安全");}}void setRecordingQuality(const std::string& quality) {recordingQuality_ = quality;std::cout << "📹 摄像头 " << name_ << " 画质设置为: " << recordingQuality_ << std::endl;}
};// 具体同事类:智能音箱
class SmartSpeaker : public SmartDevice {
private:int volume_;std::string playingContent_;std::vector<std::string> voiceCommands_;public:SmartSpeaker(HomeMediator* mediator, const std::string& name,const std::string& id, const std::string& location = "客厅"): SmartDevice(mediator, name, id, location), volume_(50), playingContent_("无") {std::cout << "🔊 创建智能音箱: " << name_ << std::endl;}void turnOn() override {std::cout << "🔊 音箱 " << name_ << " 开启" << std::endl;sendMessage("音箱已开启");}void turnOff() override {std::cout << "🔊 音箱 " << name_ << " 关闭" << std::endl;sendMessage("音箱已关闭");}void setValue(int value) override {volume_ = std::max(0, std::min(100, value));std::cout << "🔊 音箱 " << name_ << " 音量设置为: " << volume_ << std::endl;sendMessage("音量设置为 " + std::to_string(volume_));}void receiveMessage(const std::string& message, SmartDevice* sender) override {std::cout << "🔊 音箱 " << name_ << " 收到来自 " << sender->getName() << " 的消息: " << message << std::endl;// 音箱可以朗读重要消息if (message.find("警报") != std::string::npos || message.find("注意") != std::string::npos) {std::cout << "🔊 音箱朗读: " << message << std::endl;}}void receiveCommand(const std::string& command, SmartDevice* sender) override {std::cout << "🔊 音箱 " << name_ << " 收到来自 " << sender->getName() << " 的命令: " << command << std::endl;if (command.find("音量") != std::string::npos) {try {int vol = std::stoi(command.substr(command.find("音量") + 2));setValue(vol);} catch (...) {std::cout << "❌ 无效的音量命令: " << command << std::endl;}} else if (command == "播放音乐") {playMusic();} else if (command == "停止播放") {stopPlaying();}}std::string getStatus() const override {return "音量:" + std::to_string(volume_) + " 播放:" + playingContent_;}std::string getDeviceType() const override {return "智能音箱";}void displayInfo() const override {SmartDevice::displayInfo();std::cout << " 状态: " << getStatus() << std::endl;std::cout << " 语音命令: " << voiceCommands_.size() << " 条" << std::endl;}// 智能音箱特有方法void playMusic() {playingContent_ = "背景音乐";std::cout << "🎵 音箱 " << name_ << " 开始播放音乐" << std::endl;sendMessage("开始播放音乐");}void stopPlaying() {playingContent_ = "无";std::cout << "🎵 音箱 " << name_ << " 停止播放" << std::endl;sendMessage("停止播放");}void processVoiceCommand(const std::string& command) {voiceCommands_.push_back(command);std::cout << "🎤 音箱 " << name_ << " 处理语音命令: " << command << std::endl;// 简单的语音命令处理if (command.find("开灯") != std::string::npos) {broadcast("语音命令: 请打开灯光");} else if (command.find("关灯") != std::string::npos) {broadcast("语音命令: 请关闭灯光");} else if (command.find("温度") != std::string::npos) {broadcast("语音命令: 请调整温度");}}
};// 高级中介者:场景协调器
class SceneCoordinator : public HomeMediator {
private:std::unique_ptr<SmartHomeCenter> baseMediator_;std::map<std::string, std::vector<std::function<bool()>>> sceneConditions_;std::map<std::string, std::vector<std::function<void()>>> sceneActions_;public:SceneCoordinator(const std::string& name): baseMediator_(std::make_unique<SmartHomeCenter>(name)) {std::cout << "🎭 创建场景协调器: " << name << std::endl;initializeScenes();}void sendMessage(const std::string& message, SmartDevice* sender) override {baseMediator_->sendMessage(message, sender);}void sendCommand(const std::string& command, SmartDevice* sender, SmartDevice* receiver) override {baseMediator_->sendCommand(command, sender, receiver);}void broadcast(const std::string& message, SmartDevice* sender) override {baseMediator_->broadcast(message, sender);}void registerDevice(SmartDevice* device) override {baseMediator_->registerDevice(device);}void unregisterDevice(SmartDevice* device) override {baseMediator_->unregisterDevice(device);}void activateScene(const std::string& sceneName) override {std::cout << "🎭 场景协调器激活场景: " << sceneName << std::endl;// 检查场景条件if (checkSceneConditions(sceneName)) {// 执行场景动作executeSceneActions(sceneName);std::cout << "✅ 场景 " << sceneName << " 激活成功" << std::endl;} else {std::cout << "❌ 场景 " << sceneName << " 条件不满足,无法激活" << std::endl;}}void saveScene(const std::string& sceneName) override {baseMediator_->saveScene(sceneName);std::cout << "🎭 场景协调器保存场景: " << sceneName << std::endl;}std::string getSystemStatus() const override {return baseMediator_->getSystemStatus() + "\n 场景协调器: 运行中";}std::string getMediatorName() const override {return "场景协调器[" + baseMediator_->getMediatorName() + "]";}// 场景协调器特有方法void addSceneCondition(const std::string& sceneName, std::function<bool()> condition) {sceneConditions_[sceneName].push_back(condition);}void addSceneAction(const std::string& sceneName, std::function<void()> action) {sceneActions_[sceneName].push_back(action);}void autoDetectAndActivateScene() {std::cout << "🎭 场景协调器自动检测场景..." << std::endl;for (const auto& [sceneName, conditions] : sceneConditions_) {if (checkSceneConditions(sceneName)) {std::cout << "🔍 检测到适合的场景: " << sceneName << std::endl;activateScene(sceneName);break;}}}private:void initializeScenes() {// 初始化默认场景initializeGoodMorningScene();initializeGoodNightScene();initializeCinemaScene();}void initializeGoodMorningScene() {std::string sceneName = "早安场景";addSceneCondition(sceneName, []() {auto now = std::chrono::system_clock::now();std::time_t time = std::chrono::system_clock::to_time_t(now);std::tm* localTime = std::localtime(&time);return localTime->tm_hour >= 6 && localTime->tm_hour < 9;});addSceneAction(sceneName, [this]() {broadcast("早安场景激活:新的一天开始了!", nullptr);// 在实际系统中,这里会执行具体的设备控制});}void initializeGoodNightScene() {std::string sceneName = "晚安场景";addSceneCondition(sceneName, []() {auto now = std::chrono::system_clock::now();std::time_t time = std::chrono::system_clock::to_time_t(now);std::tm* localTime = std::localtime(&time);return localTime->tm_hour >= 22 || localTime->tm_hour < 6;});addSceneAction(sceneName, [this]() {broadcast("晚安场景激活:祝您晚安!", nullptr);// 在实际系统中,这里会执行具体的设备控制});}void initializeCinemaScene() {std::string sceneName = "影院场景";addSceneCondition(sceneName, []() {// 简化的条件检测return true; // 实际系统中会有更复杂的条件});addSceneAction(sceneName, [this]() {broadcast("影院场景激活:享受电影时光!", nullptr);});}bool checkSceneConditions(const std::string& sceneName) {auto it = sceneConditions_.find(sceneName);if (it == sceneConditions_.end()) {return false;}for (const auto& condition : it->second) {if (!condition()) {return false;}}return true;}void executeSceneActions(const std::string& sceneName) {auto it = sceneActions_.find(sceneName);if (it == sceneActions_.end()) {return;}for (const auto& action : it->second) {action();}}
};
完整测试代码
// 测试中介者模式
void testMediatorPattern() {std::cout << "=== 中介者模式测试开始 ===" << std::endl;// 创建智能家居控制中心std::cout << "\n--- 创建智能家居系统 ---" << std::endl;SmartHomeCenter homeCenter("梦想之家");// 创建各种智能设备SmartLight livingRoomLight(&homeCenter, "客厅主灯", "light001", "客厅");SmartAirConditioner livingRoomAC(&homeCenter, "客厅空调", "ac001", "客厅");SmartCurtain livingRoomCurtain(&homeCenter, "客厅窗帘", "curtain001", "客厅");SecurityCamera entranceCamera(&homeCenter, "门口摄像头", "camera001", "门口");SmartSpeaker livingRoomSpeaker(&homeCenter, "客厅音箱", "speaker001", "客厅");// 设置设备在线状态livingRoomLight.setOnline(true);livingRoomAC.setOnline(true);livingRoomCurtain.setOnline(true);entranceCamera.setOnline(true);livingRoomSpeaker.setOnline(true);// 显示设备信息std::cout << "\n--- 设备信息 ---" << std::endl;livingRoomLight.displayInfo();livingRoomAC.displayInfo();livingRoomCurtain.displayInfo();entranceCamera.displayInfo();livingRoomSpeaker.displayInfo();// 测试设备间通信std::cout << "\n--- 测试设备通信 ---" << std::endl;livingRoomLight.sendMessage("大家好,我是客厅主灯!");livingRoomAC.sendMessage("我是客厅空调,当前温度适中");// 测试命令发送std::cout << "\n--- 测试命令发送 ---" << std::endl;livingRoomLight.sendCommand("开启", &livingRoomAC); // 灯命令空调(无意义,仅测试)livingRoomSpeaker.sendCommand("音量70", &livingRoomSpeaker);// 测试广播std::cout << "\n--- 测试广播 ---" << std::endl;livingRoomSpeaker.broadcast("系统测试广播,请忽略");// 显示系统状态std::cout << "\n--- 系统状态 ---" << std::endl;std::cout << homeCenter.getSystemStatus() << std::endl;homeCenter.showDeviceStatus();// 测试场景功能std::cout << "\n--- 测试场景功能 ---" << std::endl;homeCenter.saveScene("测试场景");homeCenter.activateScene("测试场景");std::cout << "\n=== 基础中介者模式测试结束 ===" << std::endl;
}// 测试自动场景协调
void testSceneCoordination() {std::cout << "\n=== 场景协调测试开始 ===" << std::endl;// 创建场景协调器SceneCoordinator coordinator("智能场景协调器");// 创建测试设备SmartLight testLight(&coordinator, "测试灯光", "test_light", "测试房间");SmartSpeaker testSpeaker(&coordinator, "测试音箱", "test_speaker", "测试房间");testLight.setOnline(true);testSpeaker.setOnline(true);// 测试自动场景检测std::cout << "\n--- 测试自动场景检测 ---" << std::endl;coordinator.autoDetectAndActivateScene();// 测试手动场景激活std::cout << "\n--- 测试手动场景激活 ---" << std::endl;coordinator.activateScene("早安场景");coordinator.activateScene("影院场景");std::cout << "\n=== 场景协调测试结束 ===" << std::endl;
}// 测试设备间协作
void testDeviceCollaboration() {std::cout << "\n=== 设备协作测试开始 ===" << std::endl;SmartHomeCenter collaborationCenter("协作测试中心");// 创建协作设备SmartLight bedLight(&collaborationCenter, "床头灯", "bed_light", "卧室");SmartCurtain bedCurtain(&collaborationCenter, "卧室窗帘", "bed_curtain", "卧室");SmartSpeaker bedSpeaker(&collaborationCenter, "卧室音箱", "bed_speaker", "卧室");bedLight.setOnline(true);bedCurtain.setOnline(true);bedSpeaker.setOnline(true);// 模拟日常场景std::cout << "\n--- 模拟起床场景 ---" << std::endl;bedSpeaker.processVoiceCommand("早安");bedLight.turnOn();bedCurtain.open(80);std::cout << "\n--- 模拟睡眠场景 ---" << std::endl;bedSpeaker.processVoiceCommand("晚安");bedLight.turnOff();bedCurtain.close();// 显示消息历史std::cout << "\n--- 消息历史 ---" << std::endl;collaborationCenter.showMessageHistory();std::cout << "\n=== 设备协作测试结束 ===" << std::endl;
}// 实战应用:完整智能家居系统
class CompleteSmartHomeSystem {
private:std::unique_ptr<SceneCoordinator> systemCoordinator_;std::vector<std::unique_ptr<SmartDevice>> systemDevices_;public:CompleteSmartHomeSystem() {systemCoordinator_ = std::make_unique<SceneCoordinator>("家庭智能中枢");std::cout << "🚀 初始化完整智能家居系统" << std::endl;initializeSystem();}void initializeSystem() {// 创建设备systemDevices_.push_back(std::make_unique<SmartLight>(systemCoordinator_.get(), "客厅主灯", "living_light", "客厅"));systemDevices_.push_back(std::make_unique<SmartAirConditioner>(systemCoordinator_.get(), "客厅空调", "living_ac", "客厅"));systemDevices_.push_back(std::make_unique<SmartCurtain>(systemCoordinator_.get(), "客厅窗帘", "living_curtain", "客厅"));systemDevices_.push_back(std::make_unique<SecurityCamera>(systemCoordinator_.get(), "门口摄像头", "entrance_camera", "门口"));systemDevices_.push_back(std::make_unique<SmartSpeaker>(systemCoordinator_.get(), "客厅音箱", "living_speaker", "客厅"));// 设置设备在线for (auto& device : systemDevices_) {device->setOnline(true);}// 配置场景条件configureAdvancedScenes();std::cout << "✅ 系统初始化完成" << std::endl;}void runDailySimulation() {std::cout << "\n🎮 运行智能家居日常模拟..." << std::endl;std::cout << "========================" << std::endl;// 显示系统状态std::cout << systemCoordinator_->getSystemStatus() << std::endl;// 模拟一天中的不同时段simulateMorningRoutine();simulateDaytimeActivity();simulateEveningRoutine();simulateNightRoutine();std::cout << "\n✅ 日常模拟完成" << std::endl;}void emergencyTest() {std::cout << "\n🚨 紧急情况测试..." << std::endl;// 查找摄像头并触发移动侦测for (auto& device : systemDevices_) {if (auto* camera = dynamic_cast<SecurityCamera*>(device.get())) {camera->detectMotion();break;}}}private:void configureAdvancedScenes() {// 配置回家场景systemCoordinator_->addSceneCondition("回家场景", []() {// 实际系统中这里会有更复杂的条件判断return true;});systemCoordinator_->addSceneAction("回家场景", [this]() {std::cout << "🏠 回家场景激活" << std::endl;broadcastToAllDevices("欢迎回家!");});// 配置离家场景systemCoordinator_->addSceneCondition("离家场景", []() {return true;});systemCoordinator_->addSceneAction("离家场景", [this]() {std::cout << "🚪 离家场景激活" << std::endl;broadcastToAllDevices("安全模式已启动");});}void simulateMorningRoutine() {std::cout << "\n🌅 早晨例行 (6:00-9:00)" << std::endl;systemCoordinator_->activateScene("早安场景");// 模拟具体设备操作for (auto& device : systemDevices_) {if (auto* light = dynamic_cast<SmartLight*>(device.get())) {light->turnOn();light->setValue(80);} else if (auto* curtain = dynamic_cast<SmartCurtain*>(device.get())) {curtain->open(100);}}}void simulateDaytimeActivity() {std::cout << "\n🏙️ 白天活动 (9:00-18:00)" << std::endl;// 模拟语音命令for (auto& device : systemDevices_) {if (auto* speaker = dynamic_cast<SmartSpeaker*>(device.get())) {speaker->processVoiceCommand("播放音乐");break;}}}void simulateEveningRoutine() {std::cout << "\n🌆 晚间例行 (18:00-22:00)" << std::endl;for (auto& device : systemDevices_) {if (auto* light = dynamic_cast<SmartLight*>(device.get())) {light->setValue(60);light->setColor("暖黄");} else if (auto* ac = dynamic_cast<SmartAirConditioner*>(device.get())) {ac->setValue(24);}}}void simulateNightRoutine() {std::cout << "\n🌙 夜间例行 (22:00-6:00)" << std::endl;systemCoordinator_->activateScene("晚安场景");for (auto& device : systemDevices_) {if (auto* light = dynamic_cast<SmartLight*>(device.get())) {light->turnOff();} else if (auto* curtain = dynamic_cast<SmartCurtain*>(device.get())) {curtain->close();}}}void broadcastToAllDevices(const std::string& message) {for (auto& device : systemDevices_) {device->sendMessage(message);}}
};// 高级应用:智能规则引擎
class SmartRuleEngine {
private:HomeMediator* mediator_;std::vector<std::tuple<std::string, std::function<bool()>, std::function<void()>>> rules_;public:SmartRuleEngine(HomeMediator* mediator) : mediator_(mediator) {std::cout << "🧠 创建智能规则引擎" << std::endl;initializeDefaultRules();}void addRule(const std::string& name, std::function<bool()> condition, std::function<void()> action) {rules_.emplace_back(name, condition, action);std::cout << "📝 添加规则: " << name << std::endl;}void evaluateRules() {std::cout << "🔍 规则引擎评估规则..." << std::endl;for (const auto& [name, condition, action] : rules_) {if (condition()) {std::cout << "✅ 规则触发: " << name << std::endl;action();}}}void runContinuousMonitoring(int durationSeconds) {std::cout << "👀 启动持续监控 (" << durationSeconds << "秒)..." << std::endl;auto startTime = std::chrono::steady_clock::now();while (std::chrono::duration_cast<std::chrono::seconds>(std::chrono::steady_clock::now() - startTime).count() < durationSeconds) {evaluateRules();std::this_thread::sleep_for(std::chrono::seconds(2));}std::cout << "🛑 持续监控结束" << std::endl;}private:void initializeDefaultRules() {// 温度控制规则addRule("高温自动制冷",[]() { // 模拟温度检测static std::random_device rd;static std::mt19937 gen(rd());static std::uniform_int_distribution<> tempDist(20, 35);return tempDist(gen) > 28;},[this]() {mediator_->broadcast("温度过高,自动开启制冷", nullptr);});// 节能规则addRule("无人时关灯",[]() { // 模拟人员检测static std::random_device rd;static std::mt19937 gen(rd());static std::uniform_real_distribution<> dist(0, 1);return dist(gen) > 0.7; // 30%几率触发},[this]() {mediator_->broadcast("检测到无人,关闭不必要的灯光", nullptr);});}
};int main() {std::cout << "🌈 设计模式武林大会 - 中介者模式演示 🌈" << std::endl;std::cout << "=====================================" << std::endl;// 测试基础中介者模式testMediatorPattern();// 测试场景协调testSceneCoordination();// 测试设备协作testDeviceCollaboration();// 运行完整智能家居系统演示std::cout << "\n=== 完整智能家居系统演示 ===" << std::endl;CompleteSmartHomeSystem smartHome;smartHome.runDailySimulation();// 测试紧急情况smartHome.emergencyTest();// 测试规则引擎std::cout << "\n=== 智能规则引擎测试 ===" << std::endl;SmartHomeCenter ruleCenter("规则测试中心");SmartRuleEngine ruleEngine(&ruleCenter);// 添加自定义规则ruleEngine.addRule("测试规则",[]() { return true; },[]() { std::cout << "🧪 测试规则执行" << std::endl; });// 运行规则评估ruleEngine.evaluateRules();// 运行短暂监控ruleEngine.runContinuousMonitoring(6);std::cout << "\n🎉 中介者模式演示全部完成!" << std::endl;return 0;
}
中介者模式的武学心得
适用场景
- 复杂的对象交互:当对象间的交互复杂且相互依赖时
- 定制行为:当想要定制一个分布在多个类中的行为,而又不想生成太多子类时
- 中介逻辑:当对象间的交互逻辑需要集中管理和维护时
- 减少耦合:当想要减少对象间直接的引用,降低耦合度时
优点
- 减少耦合:将对象间的一对多关联转变为一对一的关联,降低耦合度
- 集中控制:将交互逻辑集中在中介者中,便于维护和修改
- 简化对象协议:用一对多的交互代替多对多的交互,使对象间协议更加简单
- 抽象耦合:使对象间的关系更加抽象,增加灵活性
缺点
- 中介者复杂:中介者可能会变得复杂和庞大,难以维护
- 上帝对象:如果设计不当,中介者可能会变成上帝对象,承担过多职责
- 性能影响:所有通信都通过中介者,可能会影响性能
武林高手的点评
Observer 赞叹道:“Mediator 兄的集中协调确实精妙!能够如此优雅地解耦对象间的直接依赖,这在复杂的交互系统中确实无人能及。”
Facade 也点头称赞:“Mediator 兄专注于对象间的交互,而我更关注子系统的简化接口。我们都有助于降低系统的耦合度。”
Mediator 谦虚回应:“诸位过奖了。每个模式都有其适用场景。在对象间交互复杂时,我的中介者模式确实能发挥重要作用。但在需要一对多的通知机制时,Observer 兄的方法更加合适。”
下章预告
在Mediator展示完他那精妙的中介艺术后,Memento 手持"记忆之书"的神秘史官走出。
“Mediator 兄的协调解耦确实精妙,但在需要保存和恢复对象状态时,需要更加完善的状态管理机制。” Memento 神秘地说道,“下一章,我将展示如何通过备忘录模式在不破坏封装性的前提下,捕获和恢复对象的内部状态!”
架构老人满意地点头:“善!对象状态的保存和恢复确实是构建健壮系统的关键。下一章,就请 Memento 展示他的状态记忆艺术!”
欲知 Memento 如何通过备忘录模式实现对象状态的保存和恢复,且听下回分解!