今天要写的是观察者模式,还是老规矩先上概念,有好的理论基础和理论思想做引导,才能写出好代码。
观察者模式:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都得到通知并作出更新。
下面的例子是以前在项目里面写过的一个简单案例,观察的Subject是游戏的控制器,观察者对象在控制器低电量或者是连接异常
的时候得到通知并作出相应的反应
首先,定义一个抽象的观察者接口,注意我们的观察者可以同时观察多个Subject对象,因为游戏的控制器可能是多个的。
这里我将specificFun定义成了私有,是为了得到更好的封装性:
#ifndef _OBSERVER_H
#define _OBSERVER_H
#include <map>
enum ControllerState // controller's state
{
E_NORMAL,
E_POWEROFF,
E_DISCONNECTED,
};
class Controller;
//---------------define interface---------------------
class observer
{
public:
virtual ~observer(){}
/*
* called by subject's method ,notify()
*/
virtual void handler( Controller* controller )=0;
virtual void addSubject( Controller* controller )=0;
virtual void removeSubject( Controller* controller )=0;
private:
/*
* called by handler Fun, overrun by derived class
*/
virtual void specificFun( Controller* controller )=0;
protected:
/*
* map/list/vector, we all use list symbol to name them
*/
std::map<Controller*, ControllerState> mControllerStateList;
};
#endif//_OBSERVER_H
然后,定义具体的观察者类 ControllerObserver.h, 仅为了简单介绍一下观察者模型,所以连remove方法也没写。对于有多个观察主题的处理,需要根据自己项目的需求的不同进行自定义:
#ifndef _CONTROLLER_OBSERVER_H
#define _CONTROLLER_OBSERVER_H
class observer;
//-----------define specific observer----------------------
class ControllerObserver : public observer
{
public:
ControllerObserver();
virtual ~ControllerObserver();
virtual void handler( Controller* controller );
virtual void addSubject( Controller* controller );
private:
virtual void specificFun( Controller* controller );
};
#endif//_CONTROLLER_OBSERVER_H
给出具体的实现 ControllerObserver.cpp:
#include "ControllerObserver.h"
#include "Controller.h"
#include "Observer.h"
#include <map>
ControllerObserver::ControllerObserver()
{
}
ControllerObserver::~ControllerObserver()
{
}
void ControllerObserver::handler( Controller* controller )
{
specificFun( controller );
}
void ControllerObserver::addSubject( Controller* controller )
{
bool isfind = false;
std::map<Controller*, ControllerState>::iterator itr = mControllerStateList.begin();
for ( ; itr != mControllerStateList.end(); ++itr)
{
if ( itr->first == controller )
{
isfind = true;
break;
}
}
if ( !isfind )
{
mControllerStateList.insert( std::make_pair( controller, controller->getState() ) );
}
}
void ControllerObserver::specificFun( Controller* controller )
{
// specific disposition that you want
}
接着,定义我们的Subject类,游戏的控制器,可以拥有多个观察者,在控制器状态改变的时候通知每一个观察者并更新他们的状态:
#ifndef _CONTROLLER_H
#define _CONTROLLER_H
#include <vector>
#include "ControllerObserver.h"
class Controller
{
public:
Controller();
~Controller();
void notify();
void addObserver( observer* ob );
void setState(ControllerState state);
ControllerState getState();
private:
ControllerState mState;
std::vector<observer*> mObserverList;
};
#endif//_CONTROLLER_H
给出简单的定义,Controller.cpp:
#include "Controller.h"
Controller::Controller()
: mState(E_NORMAL)
{
}
Controller::~Controller()
{
}
void Controller::notify()
{
std::vector<observer*>::iterator itr = mObserverList.begin();
for ( ; itr != mObserverList.end(); ++itr )
{
(*itr)->handler( this );
}
}
void Controller::addObserver( observer* ob )
{
mObserverList.push_back( ob );
}
void Controller::setState( ControllerState state )
{
mState = state;
if ( mState != E_NORMAL )
{
notify();
}
}
ControllerState Controller::getState()
{
return mState;
}
该模式挺简单,但是在游戏开发中也会经常用到,在观察者里的map可以很好的管理不同Subject对象的状态情况,从而进行灵活的处理