设计模式之观察者模式(C++)

设计模式之观察者模式

观察者模式定义了一种一对多的依赖关系,让多个观察者同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。其UML图如下:
设计模式之观察者模式(C++)
在ConcretSubject内部有一个Observer的列表,当Subject的状态发生改变时,会通知列表内的所有的观察者。而观察者都实现了统一的接口,而不同的观察者在该接口中做出了不同的响应。其示例代码如下:

// ObserverModel.h文件
#pragma once
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
// 观察者
class Observer
{
public:
	virtual void Update() = 0;
};

class ConcreteObserver_0 : public Observer
{
public:
	virtual void Update()
	{
		std::cout << "ConcreteObserver_0 知道了" << std::endl;
	}
};

class ConcreteObserver_1 : public Observer
{
public:
	virtual void Update()
	{
		std::cout << "ConcreteObserver_1 知道了" << std::endl;
	}
};
// 通知者
class Subject
{
public:
	virtual void Attatch(Observer * p) = 0;
	virtual void Detach(Observer * p) = 0;
	virtual void Notify() = 0;
	virtual void changeState(std::string str)
	{
		m_str = str;
		Notify();
	}

protected:
	std::string m_str;
};
// 传统观察者模式
class ConcreteSubject : public Subject
{
public:
	ConcreteSubject()
	{
		;
	}
	~ConcreteSubject()
	{
		m_vec.clear();
	}
	virtual void Attatch(Observer * p)
	{
		m_vec.push_back(p);
	}
	virtual void Detach(Observer * p)
	{
		auto it = find(m_vec.begin(), m_vec.end(), p);
		if (m_vec.end() != it)
		{
			m_vec.erase(it);
		}
	}
	virtual void Notify()
	{
		for (auto it = m_vec.cbegin(); it != m_vec.cend(); it++)
		{
			std::cout << m_str << " ";
			(*it)->Update();
		}
	}
private:
	std::vector<Observer * > m_vec;
};

测试代码如下:

#include <iostream>
#include "ObserverModel.h"

int main()
{
	using namespace std;
	// 观察者模式
	ConcreteSubject * p = new ConcreteSubject();
	Observer * p1 = new ConcreteObserver_0();
	Observer * p2 = new ConcreteObserver_1();
	p->Attatch(p1);
	p->Attatch(p2);
	p->changeState("老板来啦");
	delete p;
	delete p2;
	delete p1;

	getchar();
	return 0;
}

测试结果如下图:
设计模式之观察者模式(C++)
观察者模式也有不足,观察者模式需要观察者需要实现相同的接口。但是如果已经些好的类或者第三方的类库则就没办法实现该功能了。所以可以稍稍改进一下,就是把Subject类中的关于观察者的列表修改为函数指针的列表。示例码如下:

// ObserverModel.h文件
#pragma once
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
// 函数指针版本
class ConcreteObserverFunc_0
{
public:
	static void func_0()
	{
		std::cout << "ConcreteObserver_0 知道了" << std::endl;
	}
};

class ConcreteObserverFunc_1
{
public:
	static void func_1()
	{
		std::cout << "ConcreteObserver_1 知道了" << std::endl;
	}
};

class SubjectFunc
{
public:
	virtual void Attatch(void (*p)()) = 0;
	virtual void Detach(void(*p)()) = 0;
	virtual void Notify() = 0;
	virtual void changeState(std::string str)
	{
		m_str = str;
		Notify();
	}
protected:
	std::string m_str;
};

class ConcreteSubjectFunc : public SubjectFunc
{
private:
	std::vector<void(*)()> m_func;
public:
	ConcreteSubjectFunc()
	{
		;
	}
	~ConcreteSubjectFunc()
	{
		m_func.clear();
	}
	virtual void Attatch(void (*p)())
	{
		m_func.push_back(p);
	}
	virtual void Detach(void(*p)())
	{
		auto it = find(m_func.begin(), m_func.end(), p);
		if (m_func.end() != it)
		{
			m_func.erase(it);
		}
	}
	virtual void Notify()
	{
		for (auto it = m_func.cbegin(); it != m_func.cend(); it++)
		{
			std::cout << m_str << " ";
			(*it)();
		}
	}
};

测试代码如下:

#include <iostream>
#include "ObserverModel.h"

int main()
{
	using namespace std;
	// 观察者模式
	ConcreteObserverFunc_0 * p1Func = new ConcreteObserverFunc_0();
	ConcreteObserverFunc_1 * p2Func = new ConcreteObserverFunc_1();
	ConcreteSubjectFunc * pFunc = new ConcreteSubjectFunc();
	pFunc->Attatch(&ConcreteObserverFunc_0::func_0);
	pFunc->Attatch(&ConcreteObserverFunc_1::func_1);
	pFunc->changeState("我的天哪");
	delete p1Func;
	delete p2Func;
	delete pFunc;

	getchar();
	return 0;
}

测试结果如下图:
设计模式之观察者模式(C++)