C++观察者模式Observer

C++观察者模式

代码实现如下

cpp 复制代码
#include <iostream>
#include <memory>
#include <vector>
#include <algorithm>

using namespace std;

//抽象观察者类
class Observer {
public:
	virtual ~Observer() = default;

	//更新观察者
	virtual void update(int state) = 0;

};


//抽象主题类
class Subject {
public:
	virtual ~Subject() = default;

	//注册观察者
	virtual void attach(std::shared_ptr<Observer> observer) = 0;
	
	//移出观察者
	virtual void detach(std::shared_ptr<Observer> observer) = 0;

	//通知所有观察者
	virtual void notify() = 0;

	//获取主题状态
	virtual int getState() const = 0;

	//设置主题状态
	virtual void setState(int state) = 0;

};

class ConcreteSubject : public Subject {
public:
	ConcreteSubject() :state(0) {

	}

	//添加
	void attach(std::shared_ptr<Observer> observer)override {
		observerVec.push_back(observer);
	}

	//移出
	void detach(std::shared_ptr<Observer> observer) override {
		auto it = std::find(observerVec.begin(), observerVec.end(), observer);		//使用算法先查找,然后移出效率更高效
		if (it != observerVec.end())
		{
			observerVec.erase(it);
		}
	}

	//通知所有已经注册的观察者对象
	void notify() override
	{
		for (const auto& obser : observerVec)
		{
			obser->update(state);
		}
	}

	int getState() const override{
		return state;
	}

	void setState(int _state) {
		state = _state;
		notify();
	}



private:
	int state;
	std::vector<std::shared_ptr<Observer>> observerVec;
};


class ConcreteObserver:public Observer {
public:
	ConcreteObserver(const std::string& _name) :observerState(0), name(_name) {};

	void update(int state) override {
		observerState = state;
		display();
	}

	void display() const
	{
		std::cout << "通知 " << name << " 更新了状态为 " << observerState << std::endl;
	}
private:
	int observerState;
	std::string name;
};

int main()
{

	//创建主题
	std::shared_ptr<ConcreteSubject> subject = std::make_shared<ConcreteSubject>();
	//创建观察者
	std::shared_ptr<ConcreteObserver> observer1 = std::make_shared<ConcreteObserver>("观察者1");
	std::shared_ptr<ConcreteObserver> observer2 = std::make_shared<ConcreteObserver>("观察者2");

	//注册观察者
	subject->attach(observer1);
	subject->attach(observer2);

	subject->setState(1);
	subject->detach(observer2);
	
	std::cout << std::endl;

	subject->setState(2);

	return 0;
}

UML图如下

观察者模式即一个观察者状态改变后,会通知内部已经注册的观察者对象改变状态,实现状态的改变。

观察者模式使用抽象基类的方法遵循了依赖颠倒原则,同时有新的具体观察者和新的具体主题时都可以进行动态扩展,符合开闭原则。但是观察者模式也存在不方便。比如在界面中使用观察者模式,点击按钮后,关闭原有的图片,显示一张新的图片,这样的两个操作,一个是close(),一个是show(),或者更多的操作,也就是说和抽象观察者中留的接口不同了。还有一个更好的实现方式,委托。

相关推荐
CodeWithMe13 分钟前
【C/C++】EBO空基类优化介绍
开发语言·c++
404.Not Found23 分钟前
Day46 Python打卡训练营
开发语言·python
love530love24 分钟前
【PyCharm必会基础】正确移除解释器及虚拟环境(以 Poetry 为例 )
开发语言·ide·windows·笔记·python·pycharm
凌辰揽月26 分钟前
Web后端基础(基础知识)
java·开发语言·前端·数据库·学习·算法
海奥华230 分钟前
go中的接口返回设计思想
开发语言·后端·golang
lifallen32 分钟前
深入浅出 Arrays.sort(DualPivotQuicksort):如何结合快排、归并、堆排序和插入排序
java·开发语言·数据结构·算法·排序算法
运维开发王义杰32 分钟前
Python: 告别 ModuleNotFoundError, 解决 pipx 环境下 sshuttle 缺少 pydivert 依赖的终极指南
开发语言·python
k要开心33 分钟前
从C到C++语法过度1
开发语言·c++
小吕学编程36 分钟前
策略模式实战:Spring中动态选择商品处理策略的实现
java·开发语言·设计模式
whoarethenext44 分钟前
使用 C/C++的OpenCV 实时播放火柴人爱心舞蹈动画
c语言·c++·opencv