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

相关推荐
刚入门的大一新生16 分钟前
C++初阶-C++入门基础
开发语言·c++
你是理想22 分钟前
wait 和notify ,notifyAll,sleep
java·开发语言·jvm
forestsea40 分钟前
Python进阶编程总结
开发语言·python·notepad++
q567315231 小时前
使用Java的HttpClient实现文件下载器
java·开发语言·爬虫·scrapy
weixin_428498491 小时前
Visual Studio 中使用 Clang 作为 C/C++ 编译器时,设置优化选项方法
c语言·c++·visual studio
菜鸡中的奋斗鸡→挣扎鸡2 小时前
第十四届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组
c语言·c++·蓝桥杯
六bring个六2 小时前
QT上位机笔记
开发语言·笔记·qt
步木木2 小时前
Qt 5.14.2入门(一)写个Hello Qt!程序
开发语言·qt
techdashen2 小时前
Rust主流框架性能比拼: Actix vs Axum vs Rocket
开发语言·后端·rust
普通网友2 小时前
内置AI与浏览器的开源终端Wave Terminal安装与远程连接内网服务器教程
开发语言·后端·golang