两个对象之间很好的交互方法!

      类或对象之间的建立联系的方法很多:如(1)用组合的方式,一个类做为另一个类的成员变量。(2)两个类都作为基类的成员,通过基类调用另一个类。(3)想办法捞到另一个类的句柄,给另一个类发消息。(4)还有,受人诟病的 全局变量也是一种方式呀。我们今天要 讨论的是通过一个 中间类 来实现两个类之间的通信。

     事出有因,项目中有一个比较简单的功能,就是下载的同时要保证界面要同时刷新。如果是mfc,发个消息    SendMessage(lListView, LVM_SETITEM, iCol, (LPARAM)(const LPLVITEM)&Myliveitem);让mfc自己去处理吧。但我用的是金山的框架,所以具体的刷新工作我还得做。我要使得负责下载的CDownLoadCmd和负责界面刷新的CAutoProductUIHandler之间通信

    我还需要两个类,一个含有注册方法的CCommandEventMediator,另一个是含有需实现接口的CUpdateEvent。

CommandEventMediator.h

#include "UpdateEvent.h"
#pragma once
class CCommandEventMediator : private set<CUpdateEvent*>
{
public:
	enum EVENT_CONSTANTS
	{
		DOWNLOADINITCOMPLETE = 1,
		DOWNLOADPROCESS = 2,
		NOFRESH = 3,        // 提示 没有更新
		UPDATECOMPLETE = 4,
		UPDATEPROCESS = 5,
		DOWNLOADCREATE = 6,
		DOWNLOADINITSTART = 7,
		UPDATEEND = 8,
		NETCONNECTFAILURE=9,
		SRVNOPUBLISHED=10,
		ALLPRODUCTUPDATERESULT=11,
	};
	void Register(CUpdateEvent *pUpdateEvent);
	void Unregister(CUpdateEvent *pUpdateEvent);
	void InvokeEvent(EVENT_CONSTANTS enumEvent, CDownLoadCmd *pDownLoadCmd = NULL,CAutoCommand *pAutoCommand = NULL );
};

typedef SingletonHolder<CCommandEventMediator, CreateUsingNew, PhoenixSingleton> TheCommandEventMediator;

1.注册,也就是把需要响应的类如:CAutoProductUIHandler的指针插入到集合set中。

void CCommandEventMediator::Register(CUpdateEvent *pUpdateEvent)
{	
	insert( pUpdateEvent );	
}
例如:CAutoProductUIHandler需要响应CDownLoadCmd下载过程中界面的刷新,这时我就得把CAutoProductUIHandler的实例做下注册。

CAutoProductUIHandler::CAutoProductUIHandler(CUpdateListDlg *pDialog)
{
	TheCommandEventMediator::Instance().Register(this);
  ...
}
2.调用事件。

void CCommandEventMediator::InvokeEvent(EVENT_CONSTANTS enumEvent, CDownLoadCmd *pDownLoadCmd,CAutoCommand *pAutoCommand )
{
	switch (enumEvent)
	{
	...
	case DOWNLOADPROCESS:
		{
			for(iterator iter = begin(); iter != end(); iter++)
			{
				CUpdateEvent*	pTemp = (*iter);
				if( pTemp )		pTemp->OnDownloadProcess( pDownLoadCmd );
			}
			break;
		}
	...
	}
}

这个InvokeEvent尤为重要,如A要给B通信,A就可以调用InvokeEvent,并用一个宏做参数,而B负责实现对应宏下面的接口。

如:我在CDownLoadCmd中调用InvokeEvent。

void CDownLoadCmd::_RefeshPos()
{
	...
	TheCommandEventMediator::Instance().InvokeEvent(CCommandEventMediator::DOWNLOADPROCESS,this);
	...
}

在CAutoProductUIHandler负责实现CUpdateEvent提供的相关接口。

class CAutoProductUIHandler : public CUpdateEvent

void CAutoProductUIHandler::OnDownloadProcess( CDownLoadCmd *pDownLoadCmd )
{
	if (m_pMainDlg->IsWindow() && m_pMainDlg->IsWindowVisible())
		RefreshItem(pDownLoadCmd->GetID());
}


3.扩展

其实,设计模式中的Observer与之非常相似。正如我们或许曾遇到的面试题一样:猫叫,老鼠跑,主人醒。

可以设计成:老鼠,主人都是继承自Observer。而猫这个类维护这个列表

	list<Observer*>::iterator it;
	it = _obvs->begin();
	for (;it != _obvs->end();it++)
	{
		//关于模版和iterator的用法
		(*it)->Update(this);
	}

老鼠和主人肯定对Update都有各自的实现。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值