C++实现观察者模式

来源:互联网 发布:mysql 查看表结构 编辑:程序博客网 时间:2024/06/04 18:41

    在工程中做代码的时候,经常会需要用到某个状态发生变化,要通知到需要了解该变化的类,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 Observervoid addObserver(Observer* ob){if ( std::find(_observers.begin(), _observers.end(), ob) == _observers.end() ){_observers.push_back(ob);}}// Deletion of Observervoid 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 Observervoid 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://observervirtual 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、结束



0 0