设计模式之观察者模式(C++)
设计模式之观察者模式
观察者模式定义了一种一对多的依赖关系,让多个观察者同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。其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;
}
测试结果如下图: