面向对象设计之依赖倒置原理

来源:互联网 发布:2k18科比捏脸数据 编辑:程序博客网 时间:2024/06/08 04:11

依赖倒置原理是罗伯特.C.马丁提出来的,其中心思想如下:

高层模块不能依赖低层模块,两者都要依赖抽象。抽象不能依赖具体,具体要依赖抽象。

 

这个原理倒置了传统的高层模块依赖低层模块的观念,提出了高层或低层模块要依赖抽象,下面我们用一个三层协议栈的例设计子来详细说明下

该原理。

 

分以下三个步骤来说明:

  • 初始设计
  • 用依赖倒置原理来修改设计
  • 依赖倒置的优点

 

初始设计

考察下面的无线电通信三层协议的代码,三层协议分别是:

  • RLC物理层
  • RLC数据链路层
  • RLC网络层

 

每一层对应一个类, 代码骨架如下:

Layers class RLC_Physical_Layer{   RLC_Datalink_Layer *m_p_RLC_Datalink_Layer;public:      void Device_Transmit(Datagram *p_Datagram)   {      Apply_Physical_Layer_Headers(p_Datagram);      Write_Message_To_Device(p_Datagram);   }   void Handle_Device_Receive(Datagram *p_Datagram)   {        Remove_Physical_Layer_Header(p_Datagram);      m_p_RLC_Datalink_Layer->Handle_Physical_Layer_Receive(p_Datagram);   }};class RLC_Datalink_Layer{   RLC_Physical_Layer *m_p_RLC_Physical_Layer;   RLC_Network_Layer *m_p_RLC_Network_Layer;public:      void Datalink_Transmit(Datagram *p_Datagram)   {      Process_Datalink_Transmit(p_Datagram);      m_p_RLC_Physical_Layer->Device_Transmit(p_Datagram);   }   void Handle_Physical_Layer_Receive(Datagram *p_Datagram)   {        Process_Datalink_Receive(p_Datagram);      m_p_RLC_Network_Layer->Handle_Network_Layer_Receive(p_Datagram);   }};class RLC_Network_Layer{   RLC_Datalink_Layer *m_p_RLC_Datalink_Layer;   Application_Layer *m_p_Application_Layer;public:      void Network_Transmit(Datagram *p_Datagram)   {      Process_Network_Layer_Transmit(p_Datagram);      m_p_RLC_Datalink_Layer->Datalink_Transmit(p_Datagram);   }   void Handle_Datalink_Layer_Receive(Datagram *p_Datagram)   {        Process_Network_Layer_Receive(p_Datagram);      m_p_Application_Layer->Handle_Application_Receive(p_Datagram);   }}; 


这不是一个好的设计,因为有如下限制:

  • 所有层都是相互依赖的,每个层的代码都需要包含其它层的头文件。
  • 层之间的联系是固定的,要实现一个新的协议的话,必须重新改写层的联系。
  • 一个层的被改变就会影响到其它层。

 

要解决以上问题, 就必须引入一个抽象层,让这些层都去依赖抽象层, 这就是依赖倒置原理的具体应用。

 

用依赖倒置原理来修改设计

先来设计一个抽象层, 该抽象层的要点如下:

  • 构造函数有两个参数,一个是上层类抽象,一个是下层类抽象,这样保证了该层跟其它层的关系。
  • 对上层发送过来的消息进行特定处理,处理完毕后调用底层传送接口发送给底层。
  • 对低层接收到的信息做特定处理,处理完毕后就调用上层接收处理接口让上层进行处理。

下面的代码设计完全解耦合了三层的关系,所有层都只依赖于抽象层了。

Protocol_Layer Abstraction // Protocol_Layer abstraction has been defined to decouple the// different protocol layers. Now the layers only depend upon// this abstraction.class Protocol_Layer{   // Each layer can associate with an upper and lower layer.   // This association is also in terms of the Protocol_Layer   // class. Thus there is no dependency on the actual types   // of individual layers. The only requirement is that they   // should inherit from Protocol_Layer.   Protocol_Layer *m_p_Lower_Layer;   Protocol_Layer *m_p_Upper_Layer;   // Each inheriting layer must override the following methods.   // These methods handle the actual protocol processing.   virtual void Process_Transmit(Datagram *p_Datagram) = 0;   virtual void Process_Receive(Datagram *p_Datagram) = 0;public:   // Create a protocol layer with the associated upper and   // lower layers.   Protocol_Layer(Protocol_Layer *p_Lower_Layer,                   Protocol_Layer *p_Upper_Layer)   {      m_p_Lower_Layer = p_Lower_Layer;       m_p_Upper_Layer = p_Upper_Layer;   }   // Process and transmit the datagram passed by higher layer.   void Transmit(Datagram *p_Datagram)   {       Process_Transmit(p_Datagram);       if (m_p_Lower_Layer)       {          m_p_Lower_Layer->Transmit(p_Datagram);       }   }   // Receive handler for a datagram received from lower layer   void Handle_Receive(Datagram *p_Datagram)   {       Process_Receive(p_Datagram);       if (m_p_Upper_Layer)       {          m_p_Upper_Layer->Handle_Receive(p_Datagram);       }    }};class RLC_Physical_Layer : public Protocol_Layer{   void Process_Transmit();   void Process_Receive();public:   RLC_Physical_Layer(Layer *p_Lower_Layer, Layer *p_Upper_Layer)   : Protocol_Layer(p_Lower_Layer, p_Upper_Layer)   { }};class RLC_Datalink_Layer : public Protocol_Layer{   void Process_Transmit();   void Process_Receive();public:   RLC_Datalink_Layer(Layer *p_Lower_Layer, Layer *p_Upper_Layer)   : Protocol_Layer(p_Lower_Layer, p_Upper_Layer)   { }};class RLC_Network_Layer : public Protocol_Layer{   void Process_Transmit();   void Process_Receive();public:   RLC_Network_Layer(Layer *p_Lower_Layer, Layer *p_Upper_Layer)   : Protocol_Layer(p_Lower_Layer, p_Upper_Layer)   { }}; 


依赖倒置的优点

  • 解耦合。
  • 灵活度高, 能随意匹配和融合各层。
  • 可以在层与层之间任意插入一个新的功能层。

 

 

 

 

 

 

 

原创粉丝点击