軟件設計模式學習(二)面向對象設計原則

面向對象設計原則

面向對象設計原則是學習設計模式的基礎,每一種設計模式都符合某一種或多種面向對象設計原則。在軟件開發中使用這些原則可以提高軟件的可維護性和可複用性,讓我們可以設計出更加靈活也更容易擴展的軟件設計,實現可維護性複用的目標。

單一職責原則

  • 定義

    一個對象應該只包含單一的職責,並且該職責被完整地封裝在一個類中。

  • 分析

    一個類承擔的職責越多,被複用的可能性越小,並且相當於將這些職責耦合在一起。因此需要將這些職責進行分離,實現高內聚、低耦合的指導方針。

開閉原則

  • 定義

    一個軟件實體應當對擴展開放,對修改關閉。也就是說在設計一個模塊,應當使這個模塊可以在不被修改的前提下被擴展。

  • 分析

    在開閉原則的定義中,軟件實體可以是一個軟件模塊、一個由多個類組成的局部結構或一個類。

    軟件的需求會隨着時間推移發生變化,如果軟件設計符合開閉原則,就可以在擴展時無須修改現有代碼,保證穩定性與延續性。

    抽象化是滿足開閉原則的關鍵,通過定義一個相對穩定的抽象層,將不同的實現行爲在具體實現層中實現。如果需要修改,無須改動抽象層,只需增加新的實體類來實現新的業務功能即可。

里氏代換原則

  • 定義

    里氏代換原則:所有引用基類(父類)的地方必須能透明地使用其子類的對象。

    說白了就是:在軟件中如果能使用其基類對象,那麼一定能使用其子類對象。把基類都替換成它的子類,程序不會產生任何錯誤。但反過來則不成立,如果一個軟件實體使用的是一個子類,那麼它不一定能使用基類。

  • 分析

    里氏代換原則是實現開閉原則的重要方式之一,在程序中儘量使用基類類型來定義對象,而在運行時再確定其子類類型,用子類對象來替代父類對象。

依賴倒轉原則

  • 定義

    高層模塊不應該依賴低層模塊,它們都應該依賴抽象。抽象不應該依賴於細節,細節應該依賴於抽象。即代碼要依賴於抽象的類,而不依賴於具體的類,要針對接口編程,不要針對實現編程。

  • 分析

    如果說開閉原則是面向對象設計的目標的話,那麼依賴倒轉原則就是面向對象設計的主要手段。下面介紹依賴倒轉原則中經常提到的兩個概念。

    • 類之間的耦合

      在面向對象系統中,兩個類之間通常可以發生三種不同的耦合關係(依賴關係)

      1. 零耦合關係:兩個類之間沒有任何耦合關係
      2. 具體耦合關係:兩個具體類之間存在一個類對另一個具體類實例的直接引用
      3. 抽象耦合關係:發生在一個具體類和抽象類之間,也可以發生在兩個抽象類之間。依賴倒轉原則要求客戶端依賴於抽象耦合。
    • 依賴注入

      簡單來說,依賴注入就是將一個類的對象傳入另一個類,注入時應該注入父類對象,而在程序運行時再通過子類對象來覆蓋父類對象。依賴注入有三種方式

      1. 構造注入:通過構造函數注入實例變量
      2. 設值注入:通過Setter方法注入實例變量
      3. 接口注入:通過接口方法注入實例變量

接口隔離原則

  • 定義

    一旦一個接口太大,則需要將它分割成一些更小的接口,使用該接口的客戶端僅需知道與之相關的方法即可。

  • 分析

    這裏的接口往往有兩種不同的含義:

    1. 一種是指一個類型所具有的方法的特徵的集合,僅僅是邏輯上的概念,接口的劃分將直接帶來類型的劃分。此時可以把接口理解成角色,一個接口只代表一個角色,每個角色都有它特有的一個接口,此時這個原則叫做角色隔離原則。
    2. 另一種是指接口僅僅提高客戶端需要的行爲,即所需的方法。接口應該儘量細化,接口中的方法進來少,每個接口只包含一個客戶端所需的角色。

合成複用原則

  • 定義

    儘量使用組合對象,而不是繼承來達到複用的目的。通俗來說,合成複用原則就是指一個新的對象裏通過關聯關係(包括組合關係和聚合關係)來使用一些已有對象,使之成爲新對象的一部分;新對象通過委派調用已有對象的方法達到複用已有功能的目的。

  • 通過繼承來實現複用很簡單,子類可以覆蓋父類方法,易於擴展。但會破壞系統的封裝性,因爲繼承會將基類的實現細節暴露給子類,這種複用又稱爲“白箱複用”。

    通過組合/聚合來複用是將一個類的對象作爲另一個類的對象的一部分。新對象可以調用已有對象的功能,這種複用又稱爲“黑箱複用”。

迪米特法則

  • 定義

    指一個軟件實體應儘可能少的與其他實體發生相互作用。當一個模塊修改時,就會盡量少的影響其他模塊,這是對軟件實體之間通信的限制,它要求軟件實體之間通信的寬度和深度。

  • 分析

    在迪米特法則中,對於一個對象,其朋友包括以下幾類:

    1. 當前對象本身(this)
    2. 以參數形式傳入到當前對象方法中的對象
    3. 當前對象的成員對象
    4. 如果當前對象的成員對象是一個集合,那麼集合中的元素也都是朋友
    5. 當前對象所創建的對象

    任何對象如果滿足上面的條件之一,就是當前對象的“朋友”,否則就是“陌生人”。

  • 分類

    • 狹義的迪米特法則

      如果兩個類之間不必彼此通信,那麼這兩個類就不應當發生直接的相互作用。如果其中一個類需要調用另一個類的某一個方法的話,可以通過第三者轉發這個調用。狹義的迪米特法則可以降低類之間的耦合,但也會造成系統不同模塊之間通信效率降低,使得系統的不同模塊之間不容易協調。

    • 廣義的迪米特法則

      指對象之間的信息流量、流向以及信息的影響的控制,主要是對信息隱藏的控制。信息的隱藏可以使各個子系統之間脫耦,每一個模塊不依賴於其他模塊存在,因此每一個模塊都可以獨立地在其他地方使用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章