在工程中做代码的时候,经常会需要用到某个状态发生变化,要通知到需要了解该变化的类,Windows编程中经常用到的是发消息,要是没有Windows的消息机制的话,自己做一套消息机制倒是可以,但也是徒增了工作量,再次想到了设计模式中的观察者模式,也可以实现这个想法,具体实现如下:
1、编写观察者和被观察者类,对该类做如下说明如下:
1.1、观察者类,需要从Observer类继承,并且重写虚函数update()
1.2、被观察者类,需要继承Observable类,并且调用addObserver()函数,添加观察者类的对象
代码如下:
#ifndef __OBSERVER_H
#define __OBSERVER_H
#include <vector>
#include <algorithm>
#include <string>
#include "YtEvent.h"
class Observable;
class Observer
{
public:
virtual void update(Observable* from, YtEvent *e) = 0;
};
class Observable
{
private:
std::vector<Observer*> _observers;
public:
Observable(){}
virtual ~Observable()
{
_observers.clear();
}
// Addition of Observer
void addObserver(Observer* ob)
{
if ( std::find(_observers.begin(), _observers.end(), ob) == _observers.end() )
{
_observers.push_back(ob);
}
}
// Deletion of Observer
void deleteObserver(const Observer* ob)
{
std::vector<Observer*>::iterator i = std::find(_observers.begin(), _observers.end(), ob);
if ( i != _observers.end() )
{
_observers.erase(i);
}
}
// It notifies Observer
void notifyObservers(YtEvent *e = NULL)
{
std::vector<Observer*>::reverse_iterator i = _observers.rbegin();
while ( i != _observers.rend() )
{
(*i++)->update(this, e);
}
}
int countObservers() const
{
return (int)_observers.size();
}
};
#endif //__OBSERVER_H
2、观察者类需要继承自Observer,并且重写了update()函数,在该函数中判断,如果发生的事件是自己期望的,update()函数就会被调用。
示例代码如下:
class Test1 : public Observer
{
public:
//observer
virtual void update(Observable* from, YtEvent *e)
{
if(NULL == e)
return;
std::string szEvent = e->getEvent();
if(szEvent == "start_update")
{
printf("I find a Update Message.\n");
}
}
};
3、被观察者类需要继承自Observable,其中定义了一个value变量,需要实现的是,如果value发生变化,那么通知Test1类知道。
示例代码如下:
#ifndef __DOC_DATA_
#define __DOC_DATA_
#include "Observer.h"
class CDoc : public Observable
{
public:
CDoc()
{
value = 0;
}
~CDoc()
{
value = -1;
}
void setValue(int arg)
{
value= arg;
}
int getValue()
{
return value;
}
private:
int value;
};
#endif
4、被监视的类CDoc,调用addObserver()函数添加观察者类(函数参数要进行转换),定义某事件,把发生该事件的消息通过调用notifyObservers()函数通知观察者类
测试代码如下:
// ObserverTest.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "Observer.h"
#include "Test1.h"
#include "DocData.h"
#include "YtEvent.h"
void main()
{
CDoc data;
TestOBSERVER1 test;
char aa[128];
data.addObserver(static_cast<Observer*>(&test));
YtEvent yet("start_update");
data.notifyObservers(&yet);
printf("aaaaaaaaaaaaaaaaaaaaaaa\n");
scanf("%s", aa);
}
5、结束