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

相关推荐
yudiandian20144 分钟前
【QT 5.12.12 打包-Windows 平台下】
开发语言·qt
要记得喝水5 分钟前
C#某公司面试题(含题目和解析)--1
开发语言·windows·面试·c#·.net
金融数据出海19 分钟前
黄金金融期货数据API对接技术文档
开发语言·金融·github
诗书画唱35 分钟前
【前端教程】JavaScript 实现图片鼠标悬停切换效果与==和=的区别
开发语言·前端·javascript
岁忧37 分钟前
(LeetCode 面试经典 150 题) 200. 岛屿数量(深度优先搜索dfs || 广度优先搜索bfs)
java·c++·leetcode·面试·go·深度优先
一枝小雨1 小时前
【OJ】C++ vector类OJ题
数据结构·c++·算法·leetcode·oj题
一枝小雨1 小时前
【C++】Vector完全指南:动态数组高效使用
开发语言·c++·笔记·vector·学习笔记·std库
诗书画唱1 小时前
【前端教程】JavaScript DOM 操作实战案例详解
开发语言·前端·javascript
buyutang_1 小时前
C/C++ Linux系统编程:线程控制详解,从线程创建到线程终止
linux·c语言·c++·学习