观察者模式

#include <iostream>
#include <vector>
#include <string>

using namespace std;

class Subject;

class Observer
{
public:
	Observer() {}
	Observer(Subject* pobjSubject, string strName) : m_pobjSubject(pobjSubject), m_strName(strName) {}
	void setName(const string& strName) { m_strName = strName; }
	const string& getName() { return m_strName; }
	void setSubject(Subject* pobjSubject) { m_pobjSubject = pobjSubject; }
	virtual void notify() = 0;
protected:
	string m_strName;
	Subject* m_pobjSubject = nullptr;
};

class Subject
{
public:
	void setState(const string& strState) { m_strState = strState; }
	const string& getState() { return m_strState; }
	void addObserver(Observer* pobjObserver) { m_vecObserver.push_back(pobjObserver); }
	void removeObserver(Observer* pobjObserver)
	{
		for (auto& it = m_vecObserver.begin(); it != m_vecObserver.end();)
		{
			if ((*it)->getName() == pobjObserver->getName())
			{
				delete (*it);
				it = m_vecObserver.erase(it);
			}
			else
			{
				++it;
			}
		}
	}
	void updateObserver()
	{
		for (auto& it : m_vecObserver)
		{
			if (it)
			{
				it->notify();
			}
		}
	}
protected:
	string m_strState;
	vector<Observer*> m_vecObserver;
};

class Boss : public Subject
{
};

class Secretary : public Subject
{
};

class StockObserver : public Observer
{
public:
	StockObserver() {}
	StockObserver(Subject* pobjSubject, string strName) : Observer(pobjSubject, strName) {}
	virtual void notify() override
	{
		if (m_pobjSubject)
		{
			cout << "给" << m_strName << m_pobjSubject->getState() << endl;
		}
	}
};

int main()
{
	Subject* pobjBoss = new Boss();
	Observer* pobjStockObserver = new StockObserver(pobjBoss, "彳亍");
	pobjBoss->addObserver(pobjStockObserver);
	pobjBoss->setState("升职加薪");
	pobjBoss->updateObserver();
	return 0;
}

第一版的观察者模式缺陷是如果这个类是已经设计好的,那就没法再去改变这个类的代码,也就无法实现观察者模式,这个版本的实现在于所有的类必须是可以修改代码的。

#include <iostream>
#include <vector>
#include <string>

using namespace std;

class Subject;

class Observer
{
public:
	Observer() {}
	Observer(Subject* pobjSubject, string strName) : m_pobjSubject(pobjSubject), m_strName(strName) {}
	void setName(const string& strName) { m_strName = strName; }
	const string& getName() { return m_strName; }
	void setSubject(Subject* pobjSubject) { m_pobjSubject = pobjSubject; }
	virtual void notify() = 0;
protected:
	string m_strName;
	Subject* m_pobjSubject = nullptr;
};

class IDelegate
{
public:
	virtual void invoke() = 0;
};

template<typename T>
class Delegate : public IDelegate
{
public:
	Delegate(T* pT, void(T::*pFunction)()) : m_pT(pT), m_pFunction(pFunction) {}
	virtual void invoke() override
	{
		(m_pT->*m_pFunction)();
	}
private:
	T* m_pT;
	void(T::*m_pFunction)();
};

class Subject
{
private:
	typedef void (Observer::*function)();
public:
	void setState(const string& strState) { m_strState = strState; }
	const string& getState() { return m_strState; }
	void addObserver(IDelegate* pobjIDelegate) { m_vecIDelegate.push_back(pobjIDelegate); }
	void updateObserver()
	{
		for (auto& it : m_vecIDelegate)
		{
			it->invoke();
		}
	}
protected:
	string m_strState;
	vector<IDelegate*> m_vecIDelegate;
};

class Boss : public Subject
{
};

class Secretary : public Subject
{
};

class StockObserver : public Observer
{
public:
	StockObserver() {}
	StockObserver(Subject* pobjSubject, string strName) : Observer(pobjSubject, strName) {}
	virtual void notify() override
	{
		if (m_pobjSubject)
		{
			cout << "给" << m_strName << m_pobjSubject->getState() << endl;
		}
	}
};

int main()
{
	Subject* pobjBoss = new Boss();
	Observer* pobjStockObserver = new StockObserver(pobjBoss, "彳亍");
	Delegate<Observer> objDelegate(pobjStockObserver, &Observer::notify);
	pobjBoss->setState("升职加薪");
	pobjBoss->addObserver(&objDelegate);
	pobjBoss->updateObserver();
	return 0;
}
第二版的观察者模式加上了委托,这里的委托非常的简单,只是适合这个例子。

总结:观察者模式很好地完成了一个对象的改变使得不知道数量的对象都得到改变

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值