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. 总结
通过使用智能指针,我们可以有效地解决观察者模式中的生命周期问题,提高代码的安全性和可靠性。同时,这种实现方式也保持了观察者模式的灵活性和扩展性,使得系统更容易维护和升级。
热门推荐
8部欧美悬疑惊悚佳作推荐:高分经典,值得N刷!
国家卫健委提示:体重管理这样做
银杏树种植技巧|银杏叶功效与药用价值详解
春小麦种植时间
网站后台审核机制的局限与挑战,为何网站无法实现完全的自动删除功能?
“乌托邦”真的值得追求吗?
贵妃芒的成熟期和上市时间(探究贵妃芒的生长环境和品质特点)
如何高效撰写目标任务完成情况汇报?
新疆禾木村旅游攻略:最佳旅游时间、景点、住宿全攻略
如何合并电脑硬盘分区?两种实用方法详解
刘邦和项羽:历史剧中的刻板印象与真实评价
九转指标的合理运用及技巧
什么是只用湿毛巾就能完成的简易范围清洁?
虚拟号码:便利与风险并存,如何平衡使用与监管?
“95花之争”高热、“摇人式”剧宣,剧集市场终于支棱起来了?
保送清华北大的5种途径:从学科竞赛到外国语学校推荐
丁丑时是一天中的几点 丁丑时出生的命运
海运国际小包到缅甸价格表:一站式了解物流费用与服务
抑郁症发作外卖干不了怎么办
碰到拉萨天团的股怎么办?以卖出为主
4所医科大学冲击“双一流”,南方医科大学、首都医科大学上榜
深缘教育:学习画画的步骤是怎么样的?
每天坚持10分钟正念冥想可以增进幸福感和对抗抑郁
缠论中枢的新生、扩展与扩张:市场趋势分析的关键
MBTI:了解个性特点与沟通风格及 16 型分类
代码简洁之道:我们该如何规范代码的命名?
贵金属钌系列《钌在薄膜材料中的应用》
租房合同合租的如何证明
"书中寻宝"活动策划方案:从主题设定到效果评估的全流程指南
如何挑选合适的轨道插座