軟體開發『物件導向』設計模式的 五大基本原則(SOLID) [design pattern solid]
軟體開發『物件導向』設計模式的 五大基本原則(SOLID) [design pattern solid]
資料來源:http://www.andrewchen.tw/2017/04/09/20170409_NOTE_%E8%A8%AD%E8%A8%88%E6%A8%A1%E5%BC%8F%E4%BA%94%E5%A4%A7%E5%9F%BA%E6%9C%AC%E5%8E%9F%E5%89%87SOLID/
https://www.jyt0532.com/2020/03/22/lsp/
https://www.youtube.com/watch?v=pkm5jQfnKGs
01. Single Responsibility Principle,單一職責原則(SRP)
從最高維的系統角度來看,每個系統該明確規劃並解決某中問題,或是針對某個功能的實作,而不是一個功能複雜卻難用的系統。
若是從低維度往上看,程式碼中的 Function 應該遵循所謂的 Pure Function,每個函數負責好自己做的事情,一次只做一件事情,不依賴於外界任何的東西,也不多做任何其他的手腳。
單一職責原則最終的目的是 高內聚。一次做一件事情,並移除與這件事情無關的程式碼和變數,整體程式碼中的每個部分都與自己實作的功能相關,並沒有冗余的程式碼或功能。
02. Open Closed Principle,開閉原則(OCP)
一個模組應該是透過延展功能的彈性來獲得更多功能上的變化,而並非直接修改內部的程式碼。
目的是避免最原始的模組被頻繁的修改,基層模組被頻繁修改時相當難維護其穩定性,OCP 希望直接避免掉修改的機會,使用延展新功能的方式來達成不同的需求。
而新的需求就從新延展出來的模組中來實作,這樣維持舊有程式碼的安定性和新需求的彈性。
延展模組就是說物件導向中的繼承,而針對延展方式也有不同的手法,如直接繼承就有的模組並覆蓋新功能上去、繼承抽象類別、透過抽象類別的規範來實作新功能、透過多行來實作不同的新功能。
03. Liskov Substitution Principle,里氏替換原則(LSP)
在繼承中衍生出來的子類別,能完全支援父類別的功能。之所以稱做替換原則,就是指父類別成出現的地方,一定能替換成子生類別來使用。
在嘗試 LSP 時,必定要注意到不能忽略了 SRP 的觀念,避免在多次的升級或是改版中,最終導致整個系統極低的內聚力,並且相當不易拆分或刪減功能維護。
04. Interface Segregation Principles,介面隔離原則(ISP)
設計模組時避免設計龐大且同時多功能的單一介面,我們不應該大規模的假設使用者會完全符合這樣的需求。介面設計時應該力求介面的功能單一化,分割出多個單一功能的碎片,而眾多的功能介面中,使用者只需要挑出幾個符合需求的,並了解之後拼裝成對應的功能。
同樣與 SRP 有類似的觀念,當某個 API 設計越複雜越完整時,這只會導致該 API 能適用的場合越來越少,多做了不該做的事情。
ISP 即是design Pattern 中的 低耦合 目標。
05. Dependency Inversion Principle,依賴反轉原則(DIP)
重點在於誰依賴誰,是設計模式中相當重要的事情,子類別肯定依賴父類別的,而父類別不能去依賴子類別實作功能。
另一個重點是抽象類別,抽象類別不應該有太多細節,而實作類別依賴抽象細節,這之間的重點是,依賴應該是單向的,當然最好的目標是完全的沒有耦合,但繼承這個行為本身就讓某個類別依賴另一個類別,因此單向的依賴是最乾淨的,雙向的依賴,或是違反常理的依賴,會導致程式碼相當難追蹤。
總結:
五個基本原則大致上勾勒出:低耦合、高內聚、介面設計方式、繼承方式、兼容。
而實作設計模式的方式與細節重點在於讓程式碼更乾淨,更能讓後者完全了解前者所撰寫的功能,也降低在後續修改上的成本。