由于工作上需要实现多个视图随着数据更新而更新,针对这个需求最直接想到的当然是观察者模式,但思考过程中发现,如果简单的使用观察者模式,那么势必要迫使观察者和被观察者之间存在一定耦合,至少主题需要引用观察者对象.之后我想到一个解决办法,类似于windows的消息处理机制,建立了一个消息处理中心,由这个中心负责注册对于特定消息感兴趣的对象,在外界引发特定消息的时候会进入消息处理中心该消息的处理循环,凡是在消息处理中心注册过的对象会自动调用对象的对应的消息处理过程.现在这个版本还比较简单,还有很多地方需要改进,例如之后可以把消息从简单的枚举类型改成类,使消息本身可以附带一些额外的附加消息(不过对于我现在的应用已经够用了),另外消息的执行顺序也没有做处理,以及很多其他需要改善的地方,希望各位牛人批评指正,附上代码以供交流
头文件:
///
// MessageProcess.h
// Implementation of the Class CMessageCenter
// Created on: 28-八月-2014 14:18:50
// Original author:
///
#if !defined(EA_F90C9C96_E633_487e_B326_9C52E1744C9A__INCLUDED_)
#define EA_F90C9C96_E633_487e_B326_9C52E1744C9A__INCLUDED_
enum eMessageResualt
{
Message_OK,
Message_Failed,
Message_None
};
enum eMessageType
{
Message_Null,
Message_Test1,
Message_Test2
};
/**
* 消息处理接口
* @author
* @version 1.0
* @updated 28-八月-2014 15:10:04
*/
class IMessageProcessor
{
public:
virtual eMessageResualt ProcessMessage() = 0;
};
/**
* 消息中心
* @author
* @version 1.0
* @created 28-八月-2014 14:18:50
*/
class CMessageCenter
{
public:
static CMessageCenter* Instance()
{
if (m_p_instance == NULL)
{
m_p_instance = new CMessageCenter();
}
return m_p_instance;
}
static bool IsInstanceCreated()
{
if (m_p_instance)
{
return true;
}
else
{
return false;
}
}
private:
CMessageCenter();
virtual ~CMessageCenter();
public:
eMessageType GetCurrentMsg();
eMessageResualt ActivateMessage(eMessageType msg);
void RegisterMessage(eMessageType msg,IMessageProcessor* p_processor);
eMessageResualt UnRegisterMessage(eMessageType msg, const IMessageProcessor* p_processor);
private:
eMessageResualt ProcessMessage(eMessageType msg);
private:
class CGarbo // 它的唯一工作就是在析构函数中删除CSingleton的实例
{
public:
~CGarbo()
{
if (CMessageCenter::m_p_instance)
{
delete CMessageCenter::m_p_instance;
CMessageCenter::m_p_instance = NULL;
}
}
};
private:
static CMessageCenter* m_p_instance;
static CGarbo Garbo; // 定义一个静态成员,在程序结束时,系统会调用它的析构函数
map<eMessageType, set<IMessageProcessor *> > m_messagemap;
eMessageType m_current_msg; //当前消息
};
#endif // !defined(EA_F90C9C96_E633_487e_B326_9C52E1744C9A__INCLUDED_)
实现文件:
<pre name="code" class="cpp">///
// MessageProcess.cpp
// Implementation of the Class CMessageCenter
// Created on: 28-八月-2014 14:18:50
// Original author:
///
#include "StdAfx.h"
#include "MessageProcess.h"
CMessageCenter * CMessageCenter::m_p_instance = NULL;
CMessageCenter::CMessageCenter(){
}
CMessageCenter::~CMessageCenter(){
}
eMessageResualt CMessageCenter::ProcessMessage( eMessageType msg )
{
set<IMessageProcessor *> &s_p_processor = m_messagemap[msg];
if (s_p_processor.size() == 0)
{
return Message_None;
}
set<IMessageProcessor *>::iterator processor_iter;
for (processor_iter = s_p_processor.begin(); processor_iter != s_p_processor.end();
++processor_iter)
{
IMessageProcessor * p_processor = *processor_iter;
eMessageResualt msg_result = p_processor->ProcessMessage();
if (msg_result != Message_OK)
{
return msg_result;
}
}
return Message_OK;
}
void CMessageCenter::RegisterMessage( eMessageType msg, IMessageProcessor* p_processor )
{
m_messagemap[msg].insert(p_processor);
}
eMessageResualt CMessageCenter::UnRegisterMessage( eMessageType msg, const IMessageProcessor* p_processor )
{
set<IMessageProcessor *> &s_p_processor = m_messagemap[msg];
if (s_p_processor.size() == 0)
{
return Message_None;
}
set<IMessageProcessor *>::iterator processor_iter;
for (processor_iter = s_p_processor.begin(); processor_iter != s_p_processor.end();
++processor_iter)
{
IMessageProcessor * tmp_p_processor = *processor_iter;
if (tmp_p_processor == p_processor)
{
s_p_processor.erase(processor_iter);
return Message_OK;
}
}
return Message_None;
}
eMessageResualt CMessageCenter::ActivateMessage( eMessageType msg )
{
if (msg == Message_Null)
{
return Message_None;
}
m_current_msg = msg;
return ProcessMessage(m_current_msg);
}
eMessageType CMessageCenter::GetCurrentMsg()
{
return m_current_msg;
}
测试代码:
建立一个观察者类CA继承于IMessageProcessor接口,实现其ProcessMessage,在类的构造函数中将关注的消息Message_Test1注册到消息中心,在析构函数中反注册,
那么只要CA类型的对象存在,那么一旦有Messge_Test1的消息触发,就会调用CA对象相应的消息处理过程了.
<pre name="code" class="cpp">#include "MessageProcess.h"
class CA : IMessageProcessor
{
public:
CA()
{
CMessageCenter::Instance()->RegisterMessage(Message_Test1, this);
}
virtual ~CA()
{
CMessageCenter::Instance()->UnRegisterMessage(Message_Test1, this);
}
virtual eMessageResualt ProcessMessage()
{
eMessageType msg = CMessageCenter::Instance()->GetCurrentMsg();
switch (msg)
{
case Message_Test1:
AfxMessageBox(_T("Message_Test1 Actived!"));
break;
case Message_Test2:
AfxMessageBox(_T("Message_Test2 Actived!"));
break;
default:
break;
}
return Message_OK;
}
};
void OnTest()
{
CA a;
CMessageCenter::Instance()->ActivateMessage(Message_Test1);
}