C++ 观察者模式 (包含模板)

来源:互联网 发布:工艺软件有什么 编辑:程序博客网 时间:2024/06/05 17:16

由于是个人练习用的,而且时间仓促,没有想好后再来写,尽请见谅!

//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;
}

//目录结构


//执行结果



原创粉丝点击