UML类图(仅供参考)如下:
观察者模式解决的问题:
当有很多个对象依赖于一个状态值时,为了在状态值改变时统一的通知这些对象作出相应的改变,类似广播通知
源码
#include <list>
#include <string>
#include <iostream>
#include <algorithm>
// 观察者抽象类
class CObserver
{
public:
CObserver(const std::string &sName) :m_sName(sName) {}
virtual ~CObserver() {}
// 状态更新时的处理方法
virtual void UpdateState(std::string sState) = 0;
protected:
// 对象的名字,用于区分不同的观察者
std::string m_sName;
};
// 通知者抽象类
class CSubject
{
public:
virtual ~CSubject() {}
// 增加一个观察者
virtual void Attach(CObserver *observer) = 0;
// 去除一个观察者
virtual void Detach(CObserver *observer) = 0;
// 更改状态,通知观察者
virtual void Notify(const std::string &sState) = 0;
};
// 具体的观察者A
class CConcreteObserverA :public CObserver
{
public:
CConcreteObserverA(std::string sName) :CObserver(sName) {}
virtual void UpdateState(std::string sState)
{
std::cout << m_sName << " 的新状态是:" << sState << std::endl;
}
};
// 具体的通知者A
class CConcreteSubjectA :public CSubject
{
public:
// 增加一个观察者
virtual void Attach(CObserver *observer)
{
m_listObserver.push_back(observer);
}
// 去除一个观察者
virtual void Detach(CObserver *observer)
{
auto var = std::find(m_listObserver.begin(), m_listObserver.end(), observer);
if (m_listObserver.end() != var)
{
m_listObserver.erase(var);
}
}
// 更改状态,通知观察者
virtual void Notify(const std::string &sState)
{
for (auto var : m_listObserver)
{
var->UpdateState(sState);
}
}
private:
// 观察者链表
std::list<CObserver*> m_listObserver;
};
int main()
{
CConcreteObserverA observer1("程序员");
CConcreteObserverA observer2("产品经理");
CConcreteObserverA observer3("测试工程师");
CConcreteObserverA observer4("UI工程师");
CConcreteSubjectA subject;
subject.Attach(&observer1);
subject.Attach(&observer2);
subject.Attach(&observer3);
subject.Attach(&observer4);
subject.Detach(&observer2);
subject.Notify("休息");
subject.Notify("工作");
subject.Notify("出差");
}
好处
1、观察者和被观察者是抽象耦合的
2、建立一套触发机制