天天看點

DIP依賴倒置原則

一、定義

  1.高層子產品不應該依賴低層子產品,二者都應該依賴抽象

  2.抽象不應該依賴于細節。細節應該依賴于抽象

二、階層化

  1.簡單介紹

  結構良好的面向對象架構都具有清晰的層次定義,每個層次通過一個定義良好的、受控的接口向外提供了一組内聚的服務。

  對于這個陳述的簡單了解可能會緻使設計者設計出類似下圖的結構。

    

DIP依賴倒置原則

  圖中,高層的Policy層使用了低層的Mechanism層,而Mechanism層又使用了更細節的Utility層。這樣,Policy層對下面的Utility層的改動都是敏感的。 這種依賴關系是傳遞的。這是非常糟糕的。

  下圖則展示了一個更為合适的模型。 每個較高層次都為它所需要的服務聲明一個抽象接口。較低的層次實作了這些抽象接口。每個高層類都通過該抽象接口使用下一層,這樣高層就不依賴于低層。低層反而依賴于在高層中聲明的抽象服務接口。這解除了Policy層、Mechanism層和Utility層的兩兩依賴關系。

DIP依賴倒置原則

  2.倒置的接口所有權

  這裡的倒置不僅僅是依賴關系的倒置,它也是接口所有權的倒置。

  但是當應用DIP時,我們發現往往是客戶擁有抽象接口,而它們的服務者則從這些抽象接口派生。

  這就是著名的Hollywood(好萊塢)原則:"Don't call us,we'll call you.(不要找我們,我們會去找你)"。

  低層子產品實作了在高層子產品中聲明并被高層子產品調用的接口。

  Hollywood原則解釋:

//不應用IOC
class A
{
    B b = new B(); 
} 
//應用IOC 
class A 
{
    B b = null; // 你不需要自己找B,當你需要的時候,B會自動替你初始化。
    public A(B b)
    {
        this.b=b;
    }     
}          

  通過這種導緻的接口所有權,對于Mechanism層或者Utility層的任務改動都不會再影響到Policy層。而且,Policy層可以定義符合policyServiceInstance的任何上下文重用。通過倒置這些依賴關系,我們建立了一個更靈活、更持久、更易改變的結構。

  3.依賴于抽象

  依賴于抽象建議我們不應該依賴于具體類--也就是說,程式中所有的依賴關系都應該終止于抽象類或者接口。

  • 任何變量都不應該持有一個指向具體類的引用
  • 任何類都不應該從具體類派生
  • 任何方法都不應該重寫它的任何基類中的已實作了的方法 有時必須建立具體類的執行個體,而建立的子產品将會依賴它們,如果一個具體的類不太會改變,并且也不會建立其他類似的派生類,那麼依賴于它并不會造成損害。

三、結論

  事實上,這種依賴關系的導緻正是好的面向對象設計的标志所在。使用何種語言來編寫程式是無關緊要的。如果程式的依賴關系是倒置的,他就是面向對象的設計。如果程式的依賴關系不是倒置的,他就是過程化設計。

繼續閱讀