观察者模式定义了一种一对多的依赖关系,让多个观察者同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。其UML图如下: 在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; }测试结果如下图: 观察者模式也有不足,观察者模式需要观察者需要实现相同的接口。但是如果已经些好的类或者第三方的类库则就没办法实现该功能了。所以可以稍稍改进一下,就是把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; }测试结果如下图: