网站开发者排名,我们的服务理念和价值观,嵌入式网站开发培训,现在的电商平台有哪些文章目录 一、观察者模式概述二、传统代码 vs 观察者模式对比1. 传统实现#xff08;紧耦合#xff09;2. 观察者模式实现#xff08;松耦合#xff09; 三、Mermaid 类图说明四、核心设计要点1. 接口分层设计2. 通知机制实现3. 扩展性验证 五、应用场景与注意事项适用场景… 文章目录 一、观察者模式概述二、传统代码 vs 观察者模式对比1. 传统实现紧耦合2. 观察者模式实现松耦合 三、Mermaid 类图说明四、核心设计要点1. 接口分层设计2. 通知机制实现3. 扩展性验证 五、应用场景与注意事项适用场景注意事项1. 内存管理需注意观察者生命周期管理避免野指针2. 通知顺序观察者列表顺序可能影响业务逻辑3. 线程安全多线程环境下需考虑同步机制4. 异常处理单个观察者异常不应影响整体通知流程 六、现代C改进方案七、总结 一、观察者模式概述
观察者模式Observer Pattern是一种行为型设计模式用于建立对象间的一对多依赖关系。当一个对象被观察者状态发生变化时所有依赖它的对象观察者都会自动收到通知并更新。这种模式通过解耦通知方与接收方实现了系统的灵活性和可扩展性。 二、传统代码 vs 观察者模式对比
1. 传统实现紧耦合
// 抽象显示元素接口强制子类实现 display 方法
class DisplayElement {
public:virtual void display() 0;
};// 具体显示类直接绑定 WeatherData 数据
class CurrentConditionsDisplay : public DisplayElement {
public:// 接收 WeatherData 的更新数据并刷新显示void update(float temp, float humidity, float pressure) {this-temp temp;this-humidity humidity;this-pressure pressure;display(); // 调用 display 展示最新数据}void display() override {std::cout Current conditions: temp F degrees and humidity % humidity std::endl;}private:float temp, humidity, pressure;
};// 被观察者类直接持有显示对象紧耦合
class WeatherData {
public:// 设置天气数据并直接触发显示更新void setMeasurements(float temp, float humidity, float pressure) {this-temp temp;this-humidity humidity;this-pressure pressure;// ❗️直接调用具体观察者方法形成硬编码依赖currentDisplay.update(temp, humidity, pressure);}private:CurrentConditionsDisplay currentDisplay; // ❗️硬编码依赖具体观察者float temp, humidity, pressure;
};问题分析
紧耦合问题WeatherData 需要直接包含具体观察者类如 CurrentConditionsDisplay扩展困难添加新观察者需要修改 WeatherData 类违反开闭原则系统难以对扩展开放对修改关闭 2. 观察者模式实现松耦合
// 抽象观察者接口定义统一的更新协议
class IObserver {
public:// 纯虚函数子类必须实现 update 方法virtual void update(float temp, float humidity, float pressure) 0;virtual ~IObserver() default; // 虚析构确保多态释放
};// 抽象被观察者接口定义观察者管理操作
class ISubject {
public:// 注册观察者virtual void registerObserver(IObserver* observer) 0;// 移除观察者virtual void removeObserver(IObserver* observer) 0;// 通知所有观察者virtual void notifyObservers() 0;
};// 具体被观察者实现
class WeatherData : public ISubject {
public:// 实现注册观察者方法void registerObserver(IObserver* observer) override {observers.push_back(observer); // 将观察者加入列表}// 实现移除观察者方法void removeObserver(IObserver* observer) override {// 使用 std::remove 重排容器然后 erase 删除observers.erase(std::remove(observers.begin(), observers.end(), observer), observers.end());}// 实现通知观察者方法void notifyObservers() override {for (auto observer : observers) {observer-update(temp, humidity, pressure); // 通过接口调用更新}}// 设置天气数据并触发通知void setMeasurements(float temp, float humidity, float pressure) {this-temp temp;this-humidity humidity;this-pressure pressure;measurementsChanged(); // 触发状态变化通知}private:// 状态变化时调用通知逻辑void measurementsChanged() {notifyObservers(); // 通知所有注册观察者}std::vectorIObserver* observers; // 存储观察者指针列表float temp, humidity, pressure;
};// 具体观察者实现
class CurrentConditionsDisplay : public IObserver {
public:// 构造函数自动注册到 WeatherDataCurrentConditionsDisplay(WeatherData weatherData) {this-weatherData.registerObserver(this); // 将自身注册为观察者}// 实现 update 方法void update(float temp, float humidity, float pressure) override {this-temp temp;this-humidity humidity;this-pressure pressure;display(); // 刷新显示}void display() {std::cout Current conditions: temp F degrees and humidity % humidity std::endl;}private:float temp, humidity, pressure;WeatherData weatherData; // 引用 WeatherData 实例
};一堆观察者一堆被观察者一堆接口被观察者提供观察者注册、解绑、通知接口被观察者提供数据更新并通知方法观察者实现被观察者注册构造方法实现更新接口实现展示方法
改进优势
松耦合WeatherData 只依赖抽象接口 IObserver可扩展性强新增观察者只需实现 IObserver 接口符合开闭原则无需修改 WeatherData 即可扩展功能 三、Mermaid 类图说明 #mermaid-svg-XAFX9HV4IsZy1JEW {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-XAFX9HV4IsZy1JEW .error-icon{fill:#552222;}#mermaid-svg-XAFX9HV4IsZy1JEW .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-XAFX9HV4IsZy1JEW .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-XAFX9HV4IsZy1JEW .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-XAFX9HV4IsZy1JEW .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-XAFX9HV4IsZy1JEW .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-XAFX9HV4IsZy1JEW .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-XAFX9HV4IsZy1JEW .marker{fill:#333333;stroke:#333333;}#mermaid-svg-XAFX9HV4IsZy1JEW .marker.cross{stroke:#333333;}#mermaid-svg-XAFX9HV4IsZy1JEW svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-XAFX9HV4IsZy1JEW g.classGroup text{fill:#9370DB;fill:#131300;stroke:none;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:10px;}#mermaid-svg-XAFX9HV4IsZy1JEW g.classGroup text .title{font-weight:bolder;}#mermaid-svg-XAFX9HV4IsZy1JEW .nodeLabel,#mermaid-svg-XAFX9HV4IsZy1JEW .edgeLabel{color:#131300;}#mermaid-svg-XAFX9HV4IsZy1JEW .edgeLabel .label rect{fill:#ECECFF;}#mermaid-svg-XAFX9HV4IsZy1JEW .label text{fill:#131300;}#mermaid-svg-XAFX9HV4IsZy1JEW .edgeLabel .label span{background:#ECECFF;}#mermaid-svg-XAFX9HV4IsZy1JEW .classTitle{font-weight:bolder;}#mermaid-svg-XAFX9HV4IsZy1JEW .node rect,#mermaid-svg-XAFX9HV4IsZy1JEW .node circle,#mermaid-svg-XAFX9HV4IsZy1JEW .node ellipse,#mermaid-svg-XAFX9HV4IsZy1JEW .node polygon,#mermaid-svg-XAFX9HV4IsZy1JEW .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-XAFX9HV4IsZy1JEW .divider{stroke:#9370DB;stroke:1;}#mermaid-svg-XAFX9HV4IsZy1JEW g.clickable{cursor:pointer;}#mermaid-svg-XAFX9HV4IsZy1JEW g.classGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-XAFX9HV4IsZy1JEW g.classGroup line{stroke:#9370DB;stroke-width:1;}#mermaid-svg-XAFX9HV4IsZy1JEW .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-XAFX9HV4IsZy1JEW .classLabel .label{fill:#9370DB;font-size:10px;}#mermaid-svg-XAFX9HV4IsZy1JEW .relation{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-XAFX9HV4IsZy1JEW .dashed-line{stroke-dasharray:3;}#mermaid-svg-XAFX9HV4IsZy1JEW #compositionStart,#mermaid-svg-XAFX9HV4IsZy1JEW .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-XAFX9HV4IsZy1JEW #compositionEnd,#mermaid-svg-XAFX9HV4IsZy1JEW .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-XAFX9HV4IsZy1JEW #dependencyStart,#mermaid-svg-XAFX9HV4IsZy1JEW .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-XAFX9HV4IsZy1JEW #dependencyStart,#mermaid-svg-XAFX9HV4IsZy1JEW .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-XAFX9HV4IsZy1JEW #extensionStart,#mermaid-svg-XAFX9HV4IsZy1JEW .extension{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-XAFX9HV4IsZy1JEW #extensionEnd,#mermaid-svg-XAFX9HV4IsZy1JEW .extension{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-XAFX9HV4IsZy1JEW #aggregationStart,#mermaid-svg-XAFX9HV4IsZy1JEW .aggregation{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-XAFX9HV4IsZy1JEW #aggregationEnd,#mermaid-svg-XAFX9HV4IsZy1JEW .aggregation{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-XAFX9HV4IsZy1JEW .edgeTerminals{font-size:11px;}#mermaid-svg-XAFX9HV4IsZy1JEW :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 1 n uses ISubject registerObserver(observer: IObserver) : void removeObserver(observer: IObserver) : void notifyObservers() : void IObserver update(temp: float, humidity: float, pressure: float) : void WeatherData -observers: std::vector setMeasurements(temp: float, humidity: float, pressure: float) : void CurrentConditionsDisplay display() : void 四、核心设计要点
1. 接口分层设计
ISubject 接口定义观察者管理方法注册/移除/通知IObserver 接口定义更新方法的标准化协议具体实现类通过组合方式实现接口协作
2. 通知机制实现
void WeatherData::notifyObservers() {for (auto observer : observers) {observer-update(temp, humidity, pressure); // 通过接口调用具体实现}
}使用迭代器遍历观察者列表通过统一接口调用更新方法实现广播-订阅通信模式
3. 扩展性验证
新增统计显示观察者只需
class StatisticsDisplay : public IObserver {
public:void update(float temp, float humidity, float pressure) override {temps.push_back(temp);// 计算统计信息...display();}void display() {std::cout Stats: Max/Min/Avg temperature... std::endl;}
private:std::vectorfloat temps;
};无需修改 WeatherData 类即可实现功能扩展 五、应用场景与注意事项
适用场景
GUI 事件处理系统如按钮点击事件实时数据监控系统分布式事件总线架构游戏中的事件驱动系统
注意事项
1. 内存管理需注意观察者生命周期管理避免野指针
2. 通知顺序观察者列表顺序可能影响业务逻辑
3. 线程安全多线程环境下需考虑同步机制
4. 异常处理单个观察者异常不应影响整体通知流程 六、现代C改进方案
使用智能指针和lambda表达式增强安全性
class ModernWeatherData : public ISubject {
public:void registerObserver(std::shared_ptrIObserver observer) override {observers.push_back(observer); // 使用智能指针避免内存泄漏}// ...其他方法...
private:std::vectorstd::shared_ptrIObserver observers; // 智能指针容器
};七、总结
特性传统实现观察者模式对象耦合度高低扩展性需修改现有代码支持开闭原则维护成本高低通知灵活性固定调用动态注册/注销适用场景复杂度简单场景复杂系统架构
观察者模式通过接口抽象和行为封装为复杂系统提供了优雅的通信解决方案。在C中实现时需注意接口设计规范、内存管理和线程安全等工程实践问题合理使用智能指针和现代C特性可进一步提升代码质量。