在软件开发过程中,网络层往往是以一个能够提供底层服务的角色出现。逻辑层是要依赖于网络层的,网络层是为逻辑层提供服务的。对于逻辑层来说,它不需要知道网络层中的具体实现,不需要知道网络层的具体对象名称;对于网络层来说,它不需要知道逻辑层中的设计。层与层之间要实现解耦合,只要网络层和逻辑层之间能够有一套契约存在,然后各自实现对契约中规定的接口编程,那么就算将来网络底层发生变动也不会影响到逻辑层的代码。 为了实现这样的效果,用一个简单的C++代码例子来说明。 假设网络层有个类CNetwork,逻辑层有个类CLogical,它们之间的契约用一个interface接口名叫INetwork。 从调用者的角度来看,创建过程理想中应该是这样的。 CNetwork* pNetwork = new CNetwork(); CLogical* pLogical = new CLogical( (INetwork*)pNetwork ); 先创建网络,再创建逻辑,逻辑要依赖于网络。当然这是理想中的,之后再来实现它。 接下来该设计它们之间契约的内容了。为了能简单说明问题,这里就只考虑网络收发的接口怎么设计了。发送可以由逻辑层直接来调用,接受可以通过回调函数由网络层主动通知逻辑层(当然网络不需要知道逻辑的设计,一切就契约来实现)。契约可以是这样的: typedef void (*RecvFunc)(WPARAM wParam, LPARAM lParam); interface INetwork { virtual void SendNetMessage(WPARAM wParam, LPARAM lParam) = 0;//网络发送 virtual void SetRecvCallBack(RecvFunc pFunc) = 0;//用来设置回调函数 }; 现在可以来实现理想中的调用方法了,在CLogical中应该有一个INetwork的接口指针 class CLogical { public: CLogical(INetwork* pNetwork); virtual ~CLogical(); static void RecvProc(WPARAM wParam, LPARAM lParam); private: INetwork* m_pNetwork; }; 构造函数中来初始化接口指针,并且把回调函数的函数指针告诉网络层。 CLogical::CLogical(INetwork* pNetwork) :m_pNetwork(pNetwork) { m_pNetwork->SetRecvCallBack(RecvProc);// 设置回调函数 } void CLogical::RecvProc(WPARAM wParam, LPARAM lParam) { // 这里就等着网络层把收到的数据发过来吧~! } 当然网络层的指责就是遵守INetwork契约来实现功能咯……因此CNetwork应该是继承于INetwork。如下: .h class CNetwork :public INetwork { public: CNetwork(); virtual ~CNetwork(); virtual void SendNetMessage(WPARAM wParam, LPARAM lParam);//网络发送功能 virtual void SetRecvCallBack(RecvFunc pFunc);// 让调用者设置回调函数 private: // …… private: RecvFunc m_pFunc;// 调用者回调函数的指针,通过它就可以把网络层接收到的数据发送给逻辑层。 }; 逻辑层始终是通过INetwork接口来使用网络的,网络对它来说是隐藏的,不知道网络的任何其它细节;网络层负责遵守INetwork契约来实现功能。这样两者就真正解藕了。 
|