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(),或者更多的操作,也就是说和抽象观察者中留的接口不同了。还有一个更好的实现方式,委托。

相关推荐
coding随想38 分钟前
JavaScript中的BOM:Window对象全解析
开发语言·javascript·ecmascript
念九_ysl1 小时前
Java 使用 OpenHTMLToPDF + Batik 将含 SVG 遮罩的 HTML 转为 PDF 的完整实践
java·开发语言·pdf
yaoxin5211231 小时前
124. Java 泛型 - 有界类型参数
java·开发语言
liulilittle2 小时前
深度剖析:OPENPPP2 libtcpip 实现原理与架构设计
开发语言·网络·c++·tcp/ip·智能路由器·tcp·通信
88号技师2 小时前
2025年6月一区-田忌赛马优化算法Tianji’s horse racing optimization-附Matlab免费代码
开发语言·算法·matlab·优化算法
勤奋的知更鸟2 小时前
Java 编程之模板方法模式
java·开发语言·模板方法模式
十年编程老舅2 小时前
跨越十年的C++演进:C++20新特性全解析
c++·c++11·c++20·c++14·c++23·c++17·c++新特性
上单带刀不带妹3 小时前
手写 Vue 中虚拟 DOM 到真实 DOM 的完整过程
开发语言·前端·javascript·vue.js·前端框架
-凌凌漆-3 小时前
【Qt】QStringLiteral 介绍
开发语言·qt