http://www.cnblogs.com/Esfog/archive/2012/04/23/2467249.html
最近在看观察者模式的时候,看到的一篇,感觉有点感觉。
在项目中使用的是lua,在观察者模式当中,是有一个事件ID和与这个事件ID绑定的函数(与其说是函数倒不如说是函数指针),这些全部存储在一个全局的对象的table当中,一个事件ID下绑定了很多的函数名(也就是函数指针),在触发了某个事件ID之后,只需要调用这个全局对象当中的一个触发函数,就可以循环触发与这个这个事件ID绑定的函数。
// 事件id
#define ENENT_ID_MIN 0
#define EVENT_ID_SHOWSELF 1
#define ENENT_ID_MAX 2
class EventBase
{
public:
virtual void OnExecute(int nEventId) = 0;
};
class EventSystem
{
public:
struct EventStruct
{
// 注册绑定的数组
list<EventBase*> arrEventBase;
EventStruct()
{
arrEventBase.clear();
}
};
vector<EventStruct> arrEventStruct;
int arrEventIndex[ENENT_ID_MAX] = {0};
int narrCount = 0;
public:
// 注册
bool Resister(int nEventId, EventBase* objEventBase = nullptr)
{
if (nEventId < ENENT_ID_MIN || nEventId > ENENT_ID_MAX)
{
return false;
}
if (nullptr == objEventBase)
{
return false;
}
// 等于0就说明第一次定义,就直接放进去就好
if (arrEventIndex[nEventId] == 0)
{
narrCount++;
EventStruct eventStruct;
eventStruct.arrEventBase.push_back(objEventBase);
arrEventStruct.push_back(eventStruct);
arrEventIndex[nEventId] = narrCount;
}
else
{
int nIndex = arrEventIndex[nEventId] - 1;
if (nIndex > arrEventStruct.size())
{
return false;
}
EventStruct* peventStruct = &(arrEventStruct[nIndex]);
auto iter = peventStruct->arrEventBase.begin();
for (; iter != peventStruct->arrEventBase.end(); iter++)
{
// 重复注册
if ((*iter) == objEventBase)
{
return false;
}
}
peventStruct->arrEventBase.push_back(objEventBase);
}
return true;
}
// 反注册
bool UnResister(int nEventId, EventBase* objEventBase = nullptr)
{
if (nEventId < ENENT_ID_MIN || nEventId > ENENT_ID_MAX)
{
return false;
}
if (nullptr == objEventBase)
{
return false;
}
if (arrEventIndex[nEventId] != 0)
{
int nIndex = arrEventIndex[nEventId] - 1;
if (nIndex > arrEventStruct.size())
{
return false;
}
EventStruct* peventStruct = &(arrEventStruct[nIndex]);
auto iter = peventStruct->arrEventBase.begin();
for (; iter != peventStruct->arrEventBase.end(); iter++)
{
// 重复注册
if ((*iter) == objEventBase)
{
peventStruct->arrEventBase.erase(iter);
break;
}
}
}
return true;
}
// 触发
bool Throw(int nEventId)
{
if (nEventId < ENENT_ID_MIN || nEventId > ENENT_ID_MAX)
{
return false;
}
if (arrEventIndex[nEventId] != 0)
{
int nIndex = arrEventIndex[nEventId] - 1;
if (nIndex > arrEventStruct.size())
{
return false;
}
EventStruct* peventStruct = &(arrEventStruct[nIndex]);
auto iter = peventStruct->arrEventBase.begin();
for (; iter != peventStruct->arrEventBase.end(); iter++)
{
(*iter)->OnExecute(nEventId);
}
return true;
}
}
};
class Person
{
public:
string strName; // 姓名
string strSex; // 性别
int nAge; // 年龄
string strProfession; // 职业
public:
void Create(string _strName, string _strSex, int _Age, string _strProfession)
{
strName = _strName;
strSex = _strSex;
nAge = _Age;
strProfession = _strProfession;
}
};
class Doctor :public Person,public EventBase
{
public:
void OnExecute(int nEvent)
{
if (nEvent == EVENT_ID_SHOWSELF)
{
cout << strName << "是一个" << nAge << "岁的" << strSex << "性" << strProfession << endl;
}
}
};
class Police :public Person, public EventBase
{
public:
void OnExecute(int nEvent)
{
if (nEvent == EVENT_ID_SHOWSELF)
{
cout << strName << "是一个" << nAge << "岁的" << strSex << "性" << strProfession << endl;
}
}
};
static EventSystem* peventSystem = nullptr;
EventSystem* GetEventSystemObj()
{
if (peventSystem == nullptr)
{
peventSystem = new EventSystem;
}
return peventSystem;
}
int main(void)
{
EventSystem* pObj = GetEventSystemObj();
if (pObj == nullptr)
{
cout << "事件系统对象出错" << endl;
return 0;
}
Police police1;
police1.Create("小刚", "男", 26, "警察");
Police police2;
police2.Create("小红", "女", 22, "警察");
Doctor doctor1;
doctor1.Create("小明", "男", 34, "儿科医生");
Doctor doctor2;
doctor2.Create("小丽", "女", 28, "护士");
pObj->Resister(EVENT_ID_SHOWSELF, static_cast<EventBase*>(&police1));
pObj->Resister(EVENT_ID_SHOWSELF, static_cast<EventBase*>(&doctor1));
pObj->Throw(EVENT_ID_SHOWSELF);
pObj->UnResister(EVENT_ID_SHOWSELF, static_cast<EventBase*>(&police1));
pObj->Resister(EVENT_ID_SHOWSELF, static_cast<EventBase*>(&police2));
pObj->Throw(EVENT_ID_SHOWSELF);
return 0;
}