C++设计模式--观察者模式(Observer)

概述

观察者模式,定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

适用场景

以下任一情况下可以使用观察者模式:

  • 当一个抽象模型有两方面,其中一个方面依赖于另一个方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
  • 当一个对象的改变需要同时改变其它对象,而不知道具体有多少对象有待改变。
  • 当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之,你不希望这些对象是紧密耦合的。

UML 类图

  • Subject(抽象目标)
    – 目标知道它的观察者。可以有任意多个观察者观察同一个目标
    – 提供住处和删除观察者对象的接口
  • Observer(观察者)
    – 为那些在目标发生改变时需获得通知的对象定义一个更新接口‘
  • ConcreteSubject(具体目标)
    – 将有关状态存入各个 ConcreteObserver 对象
    – 当它的状态发生改变时,向它的各个观察者发出通知
  • ConcreteObserver(具体观察者)
    – 维护一个指向 ConcreteSubject 对象的引用
    – 存储有关状态,这些状态应与目标的状态保持一致
    – 实现Observer的更新接口以使自身状态与目标的状态保持一致

示例

假定一个学校,若要发布向所有班级发布重要通知,需要由每个班主任一一的到自己班级上进行通知,那么这里的班主任就相当于目标主题,而每个班级的学生就是观察者。

来看下代码:
isubject.h

#include 
#include 
class IObserver;using namespace std;
//抽象目标
class ISubject
{
public:virtual ~ISubject();virtual void Attach(IObserver * o);virtual void Detach(IObserver * o);virtual void Notify(string msg);
private:list m_observers;
};//具体目标
class ConcreteSubject : public ISubject
{
public:~ConcreteSubject();void setMessage(string msg);string getMssage();private:string m_msg;
};

isubject.cpp

#include "isubject.h"
#include "iobserver.h"ISubject::~ISubject()
{}void ISubject::Attach(IObserver *o)
{m_observers.push_back(o);
}void ISubject::Detach(IObserver *o)
{m_observers.remove(o);
}void ISubject::Notify(string msg)
{list::iterator it = m_observers.begin();while (it != m_observers.end()) {(*it)->Update(msg);++it;}
}ConcreteSubject::~ConcreteSubject()
{
}void ConcreteSubject::setMessage(string msg)
{Notify(msg);
}string ConcreteSubject::getMssage()
{return  m_msg;
}

iobserver.h

#include 
#include using namespace std;//抽象观察者
class IObserver
{
public:virtual ~IObserver();virtual void Update(string msg) = 0;
};class ConcreteObserver : public IObserver
{
public:ConcreteObserver(string name);void Update(string msg);private:string m_name;
};

iobserver.cpp

#include "iobserver.h"IObserver::~IObserver()
{}ConcreteObserver::ConcreteObserver(string name):m_name(name)
{
}void ConcreteObserver::Update(string msg)
{cout << m_name << " Notification:"<< msg << endl;
}

main.cpp

#include 
#include "isubject.h"
#include "iobserver.h"using namespace std;
#define DELETE(x) {if(x){delete(x);(x) = nullptr;}}int main()
{//创建目标和观察者,这里观察者为三个班级ConcreteSubject * pSubject = new ConcreteSubject();IObserver * pObserver1 = new ConcreteObserver("classA");IObserver * pObserver2 = new ConcreteObserver("classB");IObserver * pObserver3 = new ConcreteObserver("classC");//注册观察者pSubject->Attach(pObserver1);pSubject->Attach(pObserver2);pSubject->Attach(pObserver3);//发布通知啦pSubject->Notify("Due to the weather, today’s holiday.");//删除一个班级pSubject->Detach(pObserver2);//再次通知pSubject->Notify("Pay the data fee.");DELETE(pSubject);DELETE(pObserver1);DELETE(pObserver2);DELETE(pObserver3);return 0;
}

输出:

classA Notification:Due to the weather, today’s holiday.
classB Notification:Due to the weather, today’s holiday.
classC Notification:Due to the weather, today’s holiday.
classA Notification:Pay the data fee.
classC Notification:Pay the data fee.

上述代码在这里


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部