博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++ 观察者模式 (Oberver Pattern)
阅读量:20810 次
发布时间:2019-12-03

本文共 4017 字,大约阅读时间需要 13 分钟。

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

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

//目录结构

//执行结果

你可能感兴趣的文章
kettle调用java程序_Kettle ETL调用 java代码来进行数据库的增删改查
查看>>
mysql 取两个时间差 php_在php和MySql中计算时间差的方法详解
查看>>
mysql 重启数据库实例_mysql 单机多实例重启数据库服务
查看>>
collator java_Java Collator getInstance(Locale)用法及代码示例
查看>>
dtc mysql_DTCC归来-高可用可扩展数据库架构探讨
查看>>
java怎样将日期本土化_Java中的日期操作
查看>>
java生产者消费者模型到精通_java生产者消费者模型
查看>>
java 执行 awk_3.1 biostar lesson3 linux学习日记;java版本;awk
查看>>
python函数代码块以什么开头_Python初体验-开篇 代码全析
查看>>
java闹钟程序设计_JAVA课程设计_闹钟的设计与实现项目-报告_附源代码.doc
查看>>
java中的无效的列类型_java.sql.SQLException: 无效的列类型: 1111
查看>>
php rewrite url_PHP_URL Rewrite的设置方法,URL Rewrite需要服务器的支持! - phpStudy
查看>>
php读取大文件某行内容,PHP读取和修改大文件的某行内容_PHP教程
查看>>
打印php错误日志,php怎样打印错误日志
查看>>
Calendar导入java,Java程序使用Calendar.add()方法将分钟添加到当前时间
查看>>
mysql中用户线程作用,mysql用户线程的建立与用户线程的状态源码解析
查看>>
php页面引用公共文件,WeiPHP插件模板中快速引入公共模板文件
查看>>
php tracy,admin.php
查看>>
php访问父类的所有属性,php – 在父类中使用$this仅在子类中显示父类属性
查看>>
oracle比较强大的函数,SQL和ORACLE函数比较
查看>>