※ 設計模式的五大精神介紹(S.O.L.I.D):
※ 第一大精神 — S:單一職責原則(Single responsibility principle, SRP)
※ 定義:
- 每個物件,不管是類別或函數,都應該只負責一項功能。
- 當需求改變時,僅需改相關的區域,而不需要更動其他不相關的部分。
- 這樣的設計能夠讓類別更加專注於單一責任,方便維護。
※ 第二大精神 — O:開放封閉原則(Open Close principle , OCP)
※ 常用口號:對外開放,對內封閉。
※ 定義:
- 系統的功能應該透過新增程式碼來擴充,而不是修改現有的程式碼來達成。這意味著軟體實體(例如類別、模組、函數)應該能夠在不改動原本的代碼的情況下被擴充。
※ 核心概念:
- 藉由隔離業務邏輯與附加邏輯,使業務邏輯更易於擴充,以便因應需求變化。
※ 例子:
- PHP Laravel:透過繼承MVC框架內建的Controller類別,擴充Controller層的行為。
- React.Js:透過繼承React.Component類別,擴充行為。
※ 優點:
- 讓開發人員不需要修改現有的功能,就可以增加新功能,減少回歸錯誤。
※ 第三大精神 — L:里氏替換原則(Liskov Substitution Principle, LSP)
※ 定義:
- 在程式設計中,父類別和子類別之間應該是可以互換的,而不會影響系統的正確性。這意味著,基於相同介面或基類(父類)的子類別與父類別應該能夠互換,且父類別的所有行為在子類別中也能正常運行。
※ 使用原則:
- 子類別(class)的行為應該與父類別(class)保持一致,子類別的限制不可以比父類別寬鬆。
例子:
父類別的方法要求輸入值在「>= 0 且 < 50」之間,那麼子類別的方法也必須接受相同範圍的輸入值或更嚴格,例如「>= 10 且 < 40」,但不能接受更寬鬆的範圍如「>= -1 且 < 51」。也就是說父class所擁有的不變條件,必須被保留。
實際應用:
- 在專案上,例如套件A更新了,我們期望這次更新不會影響現有程式的運行。
- 我們希望在軟體進行更新後,不會導致程式出現不兼容的問題或錯誤。
※ 目的:
保證系統在進行繼承和擴充時的行為一致性,避免由於子類別替換父類別或套件更新而導致的意外錯誤。
※ 第四大精神 — I:介面隔離原則(interface-segregation principles, ISP)
※ 定義:
- 應該針對不同需求,提供相對應的介面。
- 不應該在介面中提供包含用戶用不到的功能。
※ 目的:
遵守介面隔離原則,並利用單一職責原則和里氏替換原則中學到的概念來檢驗我們的介面設計。目的在減少類之間的耦合,讓類別更加專注於自身職責,增加系統的靈活性和可維護性。
※ 第五大精神 —D:依賴反轉原則(Dependency inversion principle, DIP)
※ 定義:
- 依賴反轉原則要求外部的模組不應直接依賴於具體的實現類別,而應該依賴於抽象的介面或抽象類別。換句話說,當一個模組需要引用其他模組時,應該透過一個介面來進行,而被引用的模組應該實現這個介面。這樣做有助於減少模組之間的耦合,提高系統的靈活性和可維護性。總的來說,高階模組不應該直接依賴於低階模組,兩者都應該依賴於抽象。