面向對象設計(2)

面向對象設計原則

  • 單一職責原則 (SRP)
  • 開閉原則 (OCP)
  • Liskov 替換原則 (LSP)
  • 接口隔離原則 (ISP)
  • 依賴倒置原則 (DIP)

  • SOLID

OCP: 開閉原則

  • 軟件模塊對擴展是開放的
    • 當需求發生改變時,可以對模塊進行擴展
  • 軟件模塊對修改是封閉的
    • 對模塊進行擴展時, 無須改動模塊的源代碼。
  • 似乎是矛盾的 ?

面向對象設計的原則 (2) : 開閉原則

這裏寫圖片描述

這裏寫圖片描述

  • 缺點:

    • 對擴展開放: 可以添加新的水果類
    • 但是每次添加新的水果類,就需要修改ShopCart中的邏輯 !
  • 重構後

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

  • 對擴展開放
    • 可以任意的添加新的水果類:香蕉,西瓜…
  • 對修改是封閉的
    • 對於ShopCart中的計算邏輯不用修改。
  • 模塊依賴於一個固定抽象體,所以對於更改是關閉的。同時通過這個抽象體派生,也可以擴展此模塊的行爲。所以關鍵是抽象 !

例子

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

重構後

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

  • 在許多方面,OCP都是面向對象設計的核心所在。遵循這個原則可以帶來面向對象技術所聲稱的巨大好處(也就是 靈活性,可重用性,以及可維護性)。然而,並不是說只要使用一種面嚮對象語言遵循了這個原則。對於應用程序中的每個部分都肆意的進行抽象並不是一個好的主意。正確的做法是,開發人員應該僅僅對程序中頻繁出現的變化的那部分做出抽象。拒接不成熟的抽象和抽象本身一樣重要。

Liskov 替換原則 (LSP)

  • 子類型能夠完全替換父類型,而不會讓調用父類型的客戶程序從行爲上有任何改變
  • 難道多態不就是爲了達到這個目標嗎?

LSP: 正方形 is a 長方形?

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

LSP: 鳥都會飛嗎

這裏寫圖片描述

某個程序員創建了一個鴕鳥類

這裏寫圖片描述

這裏寫圖片描述

  • 繼承的目的

    • 重用父類的代碼
    • 更重要的是, 複用那些使用父類的代碼(例如processAll)!!
  • LSP實際上是確保我們做的抽象不會被子類破壞

LSP和契約式設計

  • Bertrand Meyer 在 1988 年闡述了 LSP 原則與契約式設計之間的關係。使用契約式設計,類中的方法需要聲明前置條件和後置條件。前置條件爲真,則方法才能被執行。而在方法調用完成之前,方法本身將確保後置條件也成立。

  • Rectangle.setWidth的後置條件

    • Assert (( width==w ) && (height == old.height))
    • 很明顯, Square 違反了這個後置條件
  • 當通過基類(父類)的接口使用對象時, 用戶只知道基類的前置條件和後置條件

  • 派生類(子類) 只能使用相等或者更弱的前置條件類替換父類的前置條件

接口隔離原則(ISP)

  • 客戶端不應該依賴它不需要的接口

  • 類間的依賴關係應該建立在最小的接口上

    • 使用多個專門的接口比使用單一的總接口要好。
  • 防止接口污染

ISP: ATM例子

這裏寫圖片描述

ISP: 咖啡機例子

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

重構後

這裏寫圖片描述

這裏寫圖片描述

依賴倒置原則(DIP)

  • 高層模塊不應該依賴於低層模塊,二者都應該依賴於抽象
  • 抽象不應該依賴於細節。細節應該依賴於抽象。

這裏寫圖片描述

這裏寫圖片描述

DIP: 熔爐的例子

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

DIP: 打印機的例子

這裏寫圖片描述

重構後

這裏寫圖片描述

  • 使用傳統的過程化程序設計所創建出來的依賴關係結構,策略是依賴於細節的。這樣會導致策略受到細節改變的影響。面向對象的程序設計倒置了依賴關係結構,使得細節和策略都依賴於抽象,並且常常是客戶擁有服務接口。

  • 依賴關係的倒置正好是面向對象設計的標誌所在。如果程序的的依賴關係是倒置的,他就是面向對象的設計。如果程序的依賴關係不是倒置的它就是過程化的設計。

  • 依賴倒置原則對於創建可重用框架來說是必須的。同時對於構建在變化面前富有彈性的代碼也是非常重要的。由於抽象和字節被彼此隔離,所以代碼也非常容易維護。

發佈了29 篇原創文章 · 獲贊 46 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章