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. 总结
通过使用智能指针,我们可以有效地解决观察者模式中的生命周期问题,提高代码的安全性和可靠性。同时,这种实现方式也保持了观察者模式的灵活性和扩展性,使得系统更容易维护和升级。
热门推荐
编程小白必看!32位和64位软件的区别详解——从安装到开发一篇搞懂
从东京、大阪、福冈、名古屋前往静冈:全面比较旅行时间和费用
中药穴位贴敷疗法:传统中医的 “外治良方”,守护全家健康
长孙皇后:李世民心中的永恒挚爱
如何理解客户留存,如何制定客户留存策略并从中获利?
8岁女孩走失 外卖小哥暖心"送单"至派出所
手臂被人咬伤后变紫肿胀?这份专业处理指南请收好
路由器无线信道和频段带宽如何设置?设置时应注意什么?
兰香子和奇亚籽哪个减肥更好?
美国债务上限如何影响黄金市场?这些影响有哪些潜在风险?
恒河鳄:世界上最大的鳄鱼之一
为什么猫是圆脸而狗是长脸?猫科都长得差不多,它们已完美进化?
遇到蛇怎么办?一文详解安全躲避蛇的方法
减肥期间如何选择肉类?这几种肉类最适合减重
人可以极简主义到什么程度?
毕业论文开题报告格式及字体要求
股指期货开户的验资是什么?
当年能拥有一台PS2的玩家,那无疑是非常幸运的!
中国电影节的崛起:从模仿到创新,本土特色与国际影响的平衡之道
三弦《天之下》: 网络武侠小说创作的一种出路
无证驾驶交通事故怎么起诉?一文详解起诉流程与赔偿标准
拍胸片和做CT哪个辐射更大
贬值美元、发行百年零息国债 海湖庄园协议意味着什么
实验动物延寿12%至35%!中国科学家捕获新长寿基因
免疫系统的三大功能是什么 有哪些作用
双肩包选购指南:实用性与美观性并重
劳动仲裁月工资是否包含奖金和补贴
水罗兰水草养殖方法与养护要点
保温层外墙漏水维修全攻略:四种实用解决方案
探究历史上的辕门射戟:神话还是真实?