C++ 观察者模式 (Oberver Pattern)
由于是个人练习用的,而且时间仓促,没有想好后再来写,尽请见谅!
//UtilTool.h
#pragma once
#include <iostream>
#include <string>
#include <list>
using namespace std;
//Event.h
#pragma once
#include "UtilTool.h"
enum EVENT_STATE
{
EAWAKE = 0,
ESTART = 1,
ETICK = 2,
EEND = 3,
ELEAVE = 4,
EDESTROY = 5,
ENORMAL = 6,
ECLICK =7,
EOVERLAP =8
};
class Event
{
public:
Event() :mCurrentState(EVENT_STATE::EAWAKE) {}
virtual void Awake() { cout << "This is basic awake!"<<endl; };
virtual void Start() { cout << "This is basic start!"<<endl; };
virtual void Tick() { cout << "This is basic tick!"<<endl; };
virtual void End() { cout << "This is basic end!"<<endl; };
virtual void Overlap() { cout << "This is basic overlap!"<<endl; };
virtual void Destroy() { cout << "This is basic destroy!"<<endl; };
EVENT_STATE mCurrentState;
};
//Object.h
#pragma once
#include "UtilTool.h"
#include "Event.h"
class Object:public Event
{
public:
string mName;
string mDesc;
long long mId;
Object(string name, string desc,long long id) :mName(name), mDesc(desc),mId(id) {}
void ShowBaseSomeThing()
{
cout << "<--Id : " << mId << ";Name : " << mName << ";Desc :" << mDesc << "-->" << endl;
}
};
//TSubject.h
#pragma once
template<typename T>
class TSubject
{
public :
virtual void Attach(T*) = 0;
virtual void Detach(T*) = 0;
virtual void Notify() = 0;
};
//TConcreteSubject.h
#pragma once
#include "UtilTool.h"
#include "TSubject.h"
#include "TObserver.h"
#include "Event.h"
template<typename T=TObserver>
class TConcreteSubjectUI :public TSubject<typename T>
{
public:
virtual void Attach(T *);
virtual void Detach(T *);
virtual void Notify();
private :
static list<T*> *mObserverList;
};
template<typename T>
list<T*>* TConcreteSubjectUI<typename T>::mObserverList = new list<T*>();
template<typename T>
void TConcreteSubjectUI<typename T>::Attach(T* observer)
{
mObserverList->push_back(observer);
}
template<typename T>
void TConcreteSubjectUI<typename T>::Detach(T* observer)
{
mObserverList->remove(observer);
}
template<typename T>
void TConcreteSubjectUI<typename T>::Notify()
{
list<T*>::iterator it ;
for(it = mObserverList->begin(); it != mObserverList->end();++it)
{
TConcreteObserver<Object> *ob = (TConcreteObserver<Object>*)(*it);
Object* obj = ob->GetObject();
ob->UpdateState(obj);
}
}
//TObserver.h
#pragma once
template<typename T>
class TObserver
{
public :
virtual void UpdateState(T*)=0;
};
//TConcreteObserver.h
#pragma once
#include "UtilTool.h"
#include "TObserver.h"
#include "Object.h"
#include "Event.h"
template<typename T=Object>
class TConcreteObserver:public TObserver<typename T>
{
public :
TConcreteObserver(Object *obj) :mObject(obj) {}
virtual void UpdateState(T*);
Object* GetObject();
private:
Object* mObject;
};
template<typename T>
Object* TConcreteObserver<typename T>::GetObject()
{
return mObject;
}
template<typename T>
void TConcreteObserver<typename T>::UpdateState(T* object)
{
Event *event = object;
switch (event->mCurrentState)
{
case EVENT_STATE::EAWAKE:
event->Awake();
break;
case EVENT_STATE::ESTART:
event->Start();
break;
case EVENT_STATE::ETICK:
event->Tick();
break;
case EVENT_STATE::EEND:
event->End();
break;
case EVENT_STATE::EOVERLAP:
event->Overlap();
break;
case EVENT_STATE::EDESTROY:
event->Destroy();
break;
default:
break;
}
Object* ob = object;
ob->ShowBaseSomeThing();
}
//test.cpp
#include "UtilTool.h"
#include "TObserver.h"
#include "TSubject.h"
#include "TConcreteObserver.h"
#include "TConcreteSubject.h"
int main()
{
TConcreteSubjectUI<TConcreteObserver<Object>> *tb = new TConcreteSubjectUI<TConcreteObserver<Object>>();
Object *obj01 = new Object("ZhangSan","BigHead",1);
TConcreteObserver<Object> *tr = new TConcreteObserver<Object>(obj01);
Object *obj02 = new Object("LiSi", "SmallHead", 2);
TConcreteObserver<Object> *tr2 = new TConcreteObserver<Object>(obj02);
tb->Attach(tr2);
tb->Attach(tr);
tb->Notify();
obj01->mCurrentState = EVENT_STATE::EOVERLAP;
obj02->mCurrentState = EVENT_STATE::EOVERLAP;
tb->Notify();
tb->Detach(tr2);
tb->Notify();
system("pause");
return 0;
}
//目录结构
//执行结果