C++ 设计模式之观察者模式

C++ 设计模式之观察者模式

简介

1、观察者模式(Observer)是一种行为设计模式,它允许对象之间定义一种一对多的依赖关系,使得每当一个对象状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。

2、观察者模式 (Observer)应用场景包括但不限于:

2.1、当一个对象的状态改变可能影响其他对象,而且您不确定有多少对象需要被通知时。

2.2、当一个对象需要通知其他对象,同时又需要保持与这些对象的松散耦合时。

3、观察者模式 (Observer)的构成

3.1、主题(Subject):定义了添加、删除观察者以及通知所有观察者的接口。

c 复制代码
class Subject
{
public:
	virtual void attach(Observer* observer) = 0;
	virtual void detach(Observer* observer) = 0;
	virtual void notify() = 0;
};

3.2、观察者(Observer):是一个接口,定义了更新自己的方法。

c 复制代码
class Observer
{
public:
	virtual void update(int value) = 0;
};

3.3、具体主题(Concrete Subject):实现了主题接口,管理观察者并通知它们。

c 复制代码
class ConcreteSubject : public Subject
{
public:
	void attach(Observer* observer);
	void detach(Observer* observer);
	void notify();
	void setValue(int val);
private:
	std::list<Observer*> observerList;
	int value;
};

3.4、具体观察者(Concrete Observer):实现了观察者接口,并定义了自己的更新逻辑。

c 复制代码
class ConcreteObserver : public Observer
{
public:
	ConcreteObserver(std::string name);
	void update(int value);
private:
	std::string observerName;
};

4、观察者模式 (Observer)的优点

4.1、分离关注点:观察者和主题之间的抽象关系使得它们之间的关联是松散的,有助于维护和更新。

4.2、建立一种触发机制:当一个对象的状态改变时,依赖对象自动更新,无需手动去调用每一个依赖对象。

4.3、支持广播通信:主题可以通知所有依赖它的对象,而不需要知道具体的依赖细节。

5、观察者模式 (Observer)的缺点

5.1、可能引发内存泄露:如果观察者没有正确注销,可能导致对象不能被正确回收。

2、实现复杂性:需要维护观察者列表和主题之间的一致性,随着观察者数量增多,这一点可能会变得复杂。

3、更新通知顺序:如果观察者的更新依赖于特定的顺序,那么维护这个顺序可能会变得困难。

4、可能导致难以追踪的bug:错误的通知或者更新可能导致一些意想不到的副作用,调试起来可能比较困难。

简单示例

1、定义

c 复制代码
// 观察者
class Observer
{
public:
	virtual void update(int value) = 0;
};

// 主题
class Subject
{
public:
	virtual void attach(Observer* observer) = 0;
	virtual void detach(Observer* observer) = 0;
	virtual void notify() = 0;
};

// 具体的主题
class ConcreteSubject : public Subject
{
public:
	void attach(Observer* observer);
	void detach(Observer* observer);
	void notify();
	void setValue(int val);
private:
	std::list<Observer*> observerList;
	int value;
};

// 具体的观察者
class ConcreteObserver : public Observer
{
public:
	ConcreteObserver(std::string name);
	void update(int value);
private:
	std::string observerName;
};

2、实现

c 复制代码
void ConcreteSubject::attach(Observer* observer)
{
	observerList.push_back(observer);
}

void ConcreteSubject::detach(Observer* observer)
{
	observerList.remove(observer);
}

void ConcreteSubject::notify()
{
	for (auto ob : observerList)
	{
		ob->update(value);
	}
}

void ConcreteSubject::setValue(int val)
{
	value = val;
	notify();
}

ConcreteObserver::ConcreteObserver(std::string name) : observerName(name)
{

}

void ConcreteObserver::update(int value)
{
	std::cout << observerName << " received value: " << value << std::endl;
}

3、调用

c 复制代码
ConcreteSubject subject;
ConcreteObserver observer1("observer1");
ConcreteObserver observer2("observer2");
subject.attach(&observer1);
subject.attach(&observer2);
subject.setValue(1);
subject.detach(&observer1);
std::cout << std::endl;
subject.setValue(10);
相关推荐
无限进步_9 分钟前
C语言文件操作全面解析:从基础概念到高级应用
c语言·开发语言·c++·后端·visual studio
_OP_CHEN12 分钟前
C++基础:(十五)queue的深度解析和模拟实现
开发语言·c++·stl·bfs·queue·容器适配器·queue模拟实现
sulikey12 分钟前
一文彻底理解:如何判断单链表是否成环(含原理推导与环入口推算)
c++·算法·leetcode·链表·floyd·快慢指针·floyd判圈算法
起床气23325 分钟前
C++海战棋开发日记(序)
开发语言·c++
top_designer40 分钟前
告别“静态”VI手册:InDesign与AE打造可交互的动态品牌规范
设计模式·pdf·交互·vi·工作流·after effects·indesign
_码力全开_44 分钟前
P1005 [NOIP 2007 提高组] 矩阵取数游戏
java·c语言·c++·python·算法·矩阵·go
孤廖1 小时前
吃透 C++ 栈和队列:stack/queue/priority_queue 用法 + 模拟 + STL 标准实现对比
java·开发语言·数据结构·c++·人工智能·深度学习·算法
非凡的世界2 小时前
深入理解 PHP 框架里的设计模式
开发语言·设计模式·php
小龙报2 小时前
《算法通关指南---C++编程篇(3)》
开发语言·c++·算法·visualstudio·学习方法·visual studio
一叶飘零_sweeeet2 小时前
深入 Spring 内核:解密 15 种设计模式的实战应用与底层实现
java·spring·设计模式