[物件導向]基礎篇:LSP, LKP, ISP, DIP(投影片分享)
前言
上一篇文章介紹了 SOLID 六大原則中的單一職責原則,以及開放封閉原則。這篇文章則要繼續介紹下面幾個原則:
- 里氏替換原則(Liskov Substitution Principle, LSP)
- 最少知識原則(Least Knowledge Principle, LKP),又稱狄米特法則(Law of Demeter, LoD)
- 介面隔離原則(Interface Segregation Principle, ISP)
- 依賴反轉原則(Dependency Inversion Principle, DIP)
雖然看起來都很抽象,但其實都是針對前面物件導向三大特性(封裝、繼承、多型),以及兩種抽象(interface, abstract),以及前一篇文章提到的兩個原則來額外約束,以達到物件導向高內聚、低耦合的目的。
投影片
作業題目
題目程式下載:OO session 4 homework.zip
重構前的 class diagram :
重構後的 class diagram :
題目的詳細說明,以及重構後的設計,請參考之前的文章:[.NET]重構之路系列v12 –用 Decorator Pattern 讓職責分離與組合
作業整理與回顧
物件導向特性與原則回顧
結論
自己曾經嘗試自學 design patterns 三次,但總是覺得少了什麼。即使看懂了,似乎也只是在依樣畫葫蘆,而無法內化,無法揮灑自如。又或者是容易迷惑、搞混,甚至為了套用 pattern 而使用 pattern。
往往看到那種需求相當簡單,卻設計得相當複雜,或是還沒有那樣的需求,就預先使用了相當抽象、彈性的架構來設計,這些物件卻可能永遠都碰不到這樣的需求。
這些都是 over design,而 over design 對可維護性所造成的傷害,很多時候不亞於 copy/paste 或架構不具備彈性所造成的問題。
幾次自學的經驗,加上多次 training 的過程,我終於瞭解了,要學 design patterns 之前,一定要先搞懂物件導向的基礎,也就是:
- 三大特性:封裝、繼承、多型
- 兩種抽象:interfact, abstract
- 目的:高內聚、低耦合
- SOLID 原則:單一職責原則、開放封閉原則、里氏替換原則、最小知識原則、介面隔離原則、依賴反轉原則
- 基本設計原則:DRY, KISS, YAGNI
- 基本設計方式:interface-driven, intention-driven, 生成物件與使用物件分開
當這些基本內功都融會貫通了,design patterns 就像是可以十足發揮內功的招式。很多時候,甚至無招勝有招,只要符合這些基礎與約束,來滿足現有的需求,這樣就是掌握了避免 over design 的界線。
雖然,有了基本功就能達到我們要的彈性目的,但那就代表不用學習或理解 design patterns 嗎?話也不是這樣說。
Design patterns 是根據許多現實面的需求,甚至隱藏起來的潛在需求,將這些常見的問題、需求異動,與其對應的解決方案集合起來,淬煉後產出最符合一般情況的 best practice。這代表了,書上的 pattern,幾乎可以滿足最一般的情況,但我個人還是建議,不要完全的被書上 pattern 的樣子綁住。而應該根據自己的需求,掌握 design patterns 的精神,滿足物件導向的基礎與規範後,設計一個最符合您需求的解決方案,這樣才是活的設計。
當自己的設計,與 design patterns 所淬練出的 model 不相同時,請檢視與比較一下,究竟是自己的設計太過冗餘,還有精鍊的空間?還是精神符合 design patterns,不同的部分則是符合眼前特別的需求。那麼,您的設計就會多一道防線。
最後,design patterns 除了提供了淬煉後的設計模型可當參考方案以外,另一個重點是用來溝通。當不同的 developer 在討論設計模型時,往往 pattern 的名稱與基本設計模型,可以讓彼此溝通的方式一致,以便達到設計者之間的共識。
參考
- 91之ASP.NET由淺入深 不負責講座 Day21 - LSP 里氏替換原則
- 91之ASP.NET由淺入深 不負責講座 Day19 – LoD/LKP 最少知識原則
- 91之ASP.NET由淺入深 不負責講座 Day20 – ISP 介面隔離原則
- 91之ASP.NET由淺入深 不負責講座 Day22 - DIP 依賴反轉原則
blog 與課程更新內容,請前往新站位置:http://tdd.best/