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

依赖倒置原理是罗伯特.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)
   { }
};
 


依赖倒置的优点

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

 

 

 

 

 

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值