一个经典的c++实现观察者模式的实现

xingyun86 2019-8-29 720

一个经典的c++实现观察者模式的实现

#include <iostream>
#include <string>
#include <deque>
#include <map>
#include <functional>
#include <algorithm>
class Subjects;
class Observer;
//抽象观察者
class Observer
{
private:
	std::shared_ptr<std::string> _name;
	std::shared_ptr<Subjects> _subject;
	std::shared_ptr<std::map<std::string, std::string>> _act_msg_map;
public:
	const std::shared_ptr<std::string>& name() { return this->_name; }
	void name(const std::shared_ptr<std::string>& _name) { this->_name = _name; }
	const std::shared_ptr<Subjects>& subject() { return this->_subject; }
	void subject(const std::shared_ptr<Subjects>& _subject) { this->_subject = _subject; }
	const std::shared_ptr<std::map<std::string, std::string>>& act_msg_map() { return this->_act_msg_map; }
	void add_act_msg(const std::string& act, const std::string& msg) { this->_act_msg_map->insert(std::map<std::string, std::string>::value_type(act, msg)); }
	void mod_act_msg(const std::string& act, const std::string& msg) {
		auto it = this->_act_msg_map->find(act); 
		if (it != this->_act_msg_map->end())
		{
			it->second = msg;
		}
	}
	void del_act_msg(const std::string& act) {
		auto it = this->_act_msg_map->find(act);
		if (it != this->_act_msg_map->end())
		{
			this->_act_msg_map->erase(it);
		}
	}
	void act_msg_map(const std::shared_ptr<std::map<std::string, std::string>>& _act_msg_map) { this->_act_msg_map = _act_msg_map; }
	Observer(const std::shared_ptr<std::string>& _name,
		const std::shared_ptr<Subjects>& _subject,
		const std::shared_ptr<std::map<std::string, std::string>>& _act_msg_map)
	{
		this->_name = _name;
		this->_subject = _subject;
		if (_act_msg_map != nullptr)
		{
			this->_act_msg_map = _act_msg_map;
		}
		else
		{
			this->_act_msg_map = std::make_shared<std::map<std::string, std::string>>();
		}
	}
	virtual void update() = 0;
};
//抽象通知者
class Subjects
{
public:
	Subjects() {
		_action = nullptr;
		_observer_dequque = std::make_shared<std::deque<std::shared_ptr<Observer>>>();
	}
private:
	std::shared_ptr<std::string> _action;
	std::shared_ptr<std::deque<std::shared_ptr<Observer>>> _observer_dequque;
public:
	const std::shared_ptr<std::string> & action() { return _action; }
	void action(const std::shared_ptr<std::string>& __action) { _action = __action; }
	const std::shared_ptr<std::deque<std::shared_ptr<Observer>>>& observer_dequque() { return this->_observer_dequque; }
	void observer_dequque(const std::shared_ptr<std::deque<std::shared_ptr<Observer>>>& _observer_dequque) { this->_observer_dequque = _observer_dequque; }
	virtual void attach(std::shared_ptr<Observer> observer) {
		_observer_dequque->push_back(observer);
	}
	virtual void detach(std::shared_ptr<Observer> observer) {
		auto it = std::find_if(_observer_dequque->begin(), _observer_dequque->end(), [observer](auto& it) {return (observer == it); });
		if (it != _observer_dequque->end())
		{
			_observer_dequque->erase(it);
		}
	}
	virtual void notify() {
		std::for_each(_observer_dequque->begin(), _observer_dequque->end(), [](auto& it) { it->update(); });
	}
};
//具体通知者,秘书
class Secretary :public Subjects
{
public:
	virtual void attach(std::shared_ptr<Observer> observer) {
		Subjects::attach(observer);
	}
	virtual void detach(std::shared_ptr<Observer> observer) {
		Subjects::detach(observer);
	}
	virtual void notify() {
		Subjects::notify();
	}
};
//具体的观察者,看股票的
class StockObserver :public Observer
{
public:
	StockObserver(const std::shared_ptr<std::string>& _name, 
		const std::shared_ptr<Subjects>& _subject, 
		const std::shared_ptr<std::map<std::string, std::string>>& _act_msg_map)
		:Observer(_name, _subject, _act_msg_map)
	{
	}
	void update() {
		std::cout << "[" << name()->c_str() << "]recv msg:" << subject()->action()->c_str() << std::endl;
		auto it = act_msg_map()->find(subject()->action()->c_str());
		if (it != act_msg_map()->end())
		{
			std::cout << it->second.c_str() << std::endl;
		}
	}
};
//具体的观察者,看NBA的
class NBAObserver :public Observer
{
public:
	NBAObserver(const std::shared_ptr<std::string>& _name, 
		const std::shared_ptr<Subjects>& _subject, 
		const std::shared_ptr<std::map<std::string, std::string>>& _act_msg_map)
		:Observer(_name, _subject, _act_msg_map)
	{
	}
	void update()
	{
		std::cout << "[" << name()->c_str() << "]recv msg:" << subject()->action()->c_str() << std::endl;
		auto it = act_msg_map()->find(subject()->action()->c_str());
		if (it != act_msg_map()->end())
		{
			std::cout << it->second.c_str() << std::endl;
		}
	}
};
int main(int argc, char ** argv)
{
	std::map<std::string, std::string> act_msg_map = {
				{"去吃饭了!", "我马上关闭股票,装做很认真工作的样子!"},
				{"首长来了!", "我马上关闭NBA,装做很认真工作的样子!"},
	};
	//被观察的对象
	std::shared_ptr<Subjects> subject = std::make_shared<Secretary>();
	//创建观察者
	std::shared_ptr<Observer> a = std::make_shared<NBAObserver>(std::make_shared<std::string>("Player-A"), subject,
		std::make_shared<std::map<std::string, std::string>>(act_msg_map));
	std::shared_ptr<Observer> b = std::make_shared<NBAObserver>(std::make_shared<std::string>("Player-B"), subject, nullptr);
	std::shared_ptr<Observer> c = std::make_shared<StockObserver>(std::make_shared<std::string>("Player-C"), subject, nullptr);
	// 初始化行为通知消息表
	for (auto & it : act_msg_map)
	{
		b->add_act_msg(it.first, it.second);
		c->add_act_msg(it.first, it.second);
	}
	//加入观察队列
	subject->attach(a);
	subject->attach(b);
	subject->attach(c);
	//事件
	subject->action(std::make_shared<std::string>("去吃饭了!"));
	//通知
	subject->notify();
	std::cout << std::endl;
	subject->detach(c);
	//事件
	subject->action(std::make_shared<std::string>("首长来了!"));
	//通知
	subject->notify();
	return 0;
}


×
打赏作者
最新回复 (0)
只看楼主
全部楼主
返回