C++设计模式:观察者模式的优化实现
创作时间:
作者:
@小白创作中心
C++设计模式:观察者模式的优化实现
引用
CSDN
1.
https://m.blog.csdn.net/gzjimzhou/article/details/145839492
1. 引言
在 C++ 软件与设计系列课程中,观察者模式是一个重要的设计模式。本系列课程旨在深入探讨该模式的实现与优化。在之前的课程里,我们已对观察者模式有了初步认识,本次将在前两次课程的基础上,进一步深入研究,着重解决观察者生命周期问题,提升代码的安全性、灵活性、可维护性和扩展性。
2. 观察者模式基础回顾
2.1 基本概念
观察者模式包含主题(Subject)和观察者(Observer)两个核心概念。主题负责管理观察者列表,当主题发生有趣的事情时,会通知列表中的所有观察者。观察者则关注主题的状态变化,当收到通知时会做出相应的反应。
2.2 首次实现
首次实现中,我们创建了主题和观察者类。主题类可以添加、移除观察者,并在状态变化时通知所有观察者。使用
std::forward_list
存储观察者指针,通过遍历列表调用每个观察者的
notify
函数。示例代码创建了一个主题和三个观察者,展示了添加、通知和移除观察者的完整流程。
3. 优化实现
3.1 解决生命周期问题
在首次实现中,观察者模式存在一个潜在的问题:当观察者对象被删除时,主题并不知情,这可能导致悬挂指针问题。为了解决这个问题,我们可以采用智能指针来管理观察者对象。
3.2 使用智能指针
使用
std::shared_ptr
来管理观察者对象,可以确保观察者对象在所有引用都被释放后自动删除。同时,主题类需要使用
std::weak_ptr
来存储观察者,以避免循环引用问题。
3.3 完善的实现代码
下面是使用智能指针优化后的观察者模式实现代码:
#include <iostream>
#include <memory>
#include <forward_list>
// Observer interface
class Observer {
public:
virtual ~Observer() = default;
virtual void update() = 0;
};
// Subject class
class Subject {
public:
void attach(std::shared_ptr<Observer> observer) {
observers_.push_front(observer);
}
void detach(std::shared_ptr<Observer> observer) {
for (auto it = observers_.begin(); it != observers_.end(); ++it) {
if (*it == observer) {
observers_.erase_after(it);
break;
}
}
}
void notify() {
for (auto& weak_observer : observers_) {
if (auto observer = weak_observer.lock()) {
observer->update();
}
}
}
private:
std::forward_list<std::weak_ptr<Observer>> observers_;
};
// Concrete Observer
class ConcreteObserver : public Observer {
public:
void update() override {
std::cout << "Observer received update." << std::endl;
}
};
int main() {
auto subject = std::make_shared<Subject>();
auto observer1 = std::make_shared<ConcreteObserver>();
auto observer2 = std::make_shared<ConcreteObserver>();
subject->attach(observer1);
subject->attach(observer2);
subject->notify();
subject->detach(observer1);
subject->notify();
return 0;
}
4. 总结
通过使用智能指针,我们可以有效地解决观察者模式中的生命周期问题,提高代码的安全性和可靠性。同时,这种实现方式也保持了观察者模式的灵活性和扩展性,使得系统更容易维护和升级。
热门推荐
旅行不肉疼!性价比爆棚的住宿推荐
青海枸杞背后的秘密:硫磺熏制,健康风险几何?
深圳理工大学2024录取分数线(含招生计划)
药房员工岗前培训内容 全面提升专业技能
治疗软组织挫伤的消炎药有哪些
一根胡萝卜的热量是多少?胡萝卜的营养成分全解析
赖氨酸与氨基丁酸的区别
赖氨酸与氨基丁酸的区别
《绝区零》游戏背景故事:一个关于勇气与探索的末世冒险
离婚后女方户口如何处理?三种常见情况详解
合肥地铁向9线、11线时代迈进,近期建设及四期规划建设展望
山东自驾游经典线路推荐
山东自驾游海南全攻略:路线规划与旅行贴士
考研作弊的危害:不仅影响成绩,更可能影响未来职业发展
华中农大推健康套餐:结合地中海饮食与本土口味,每份仅售十余元
90亿人次出行!“非遗游”成新宠,多地景区门票“秒光”!这些概念股业绩向好
瓷砖美缝后怎么清理 美缝剂粘瓷砖上清理妙招集锦
手机电池耗电快?五种实用方法帮你减缓耗电速度
语言的魅力:良言暖人心,结交善缘广
余杭高层次人才分类目录及待遇政策详解
传统糯米发糕的制作经验与个人感悟分享
2025年黄山毛峰购买指南:耐心等待,明智选择
碧桂园回应通报批评,信息披露延迟的原因是什么?
工伤四级伤残赔偿项目及标准详解
香港国际学校优势及10所顶尖国际及私立学校盘点
八字天干作用关系精准详解
多维解析一季度经济数据:肇庆县市区谁能奋勇争先?
如何有效去黑头
氯雷他定有什么副作用
数据采集平台:提升效率的关键工具