# SOLID Principle | Notes
**Robert Cecil Martin所統整的物件導向設計原則。**
* S : 單一功能原則(Single Responsibility Principle)
* **One class should have one and only one responsibility.**
物件應該僅具有一種單一功能,based on cohesion。
* 功能(職責)定義為:「改變的原因」。
* 一個類或者模組應該只有一個職責。
* 比如有一個用於編輯和列印報表的class。這樣的一個class存在兩個職責。
第一,報表的內容可以改變(編輯)。第二,報表的格式可以改變(列印)。
這兩方面會的改變因為完全不同的起因而發生:一個是本質的修改,一個是表面的修改。
* 單一功能原則認為這事實上是兩個分離的功能,
因此他們應該分離在不同的類或者模組。
把有不同的"改變原因"的事物耦合在一起的設計是不好的,應避免。
---
* O : 開閉原則(Open-Closed Principle)
* **Software components should be open for extension, but closed for modification.**
藉由**增加新的程式碼**來擴充功能,而不是**修改原本已經存在的程式碼**來擴充功能。
* 比如**extends**、**implements**、**DI**等方式,增加新的程式碼,以實作新的需求。
* 假若為了新需求,去修改了原本code,可能會造成其他呼叫該code時出現非預期的錯誤。
---
* L : 李氏替換原則(Liskov Substitution principle)
* **Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.**
衍生類別(子類)物件可以在程式中代替其基礎類別(超類)物件。
* 比如`private IXxxService XxxServiceImpl;`
其中XxxServiceImpl(視作子類)實作IXxxService(視作父類),
所以有出現IXxxService的地方都可以用其中XxxServiceImpl替換。
---
* I : 介面隔離原則(Interface-Segregation principles)
* **Many client-specific interfaces are better than one general-purpose interface.**
也就是將大介面切成小介面,只給客戶(client)需要的小介面(role interface)。
* 客戶應該不依賴於它不使用的方法,若客戶依賴大介面會有兩個問題 :
1. 有些方法根本不會用到。
2. 如果為了其他客戶更動大介面,可能自己會受到大介面影響。
---
* D : 依賴反轉原則(Dependency Inversion principle)
* **A. High-level modules should not depend on low-level modules. Both should depend on abstractions.**
高階模組不應該依賴於低階模組,兩者都該依賴抽象。
* 若現有一controller使用serviceimpl :
相對而言controller為高階模組,serviceimpl為低階模組,
controller高度依賴serviceimpl,違反DIP
controller應該依賴於IService,再讓serviceimpl實作該介面
* **B. Abstractions should not depend on details. Details should depend on abstractions.**
抽象不應該依賴於具體實作方式。具體實作方式則應該依賴抽象。
* 建立IService,再讓serviceimpl實作該介面的行為,即為**具體實作方式依賴抽象**
---
參考 : https://www.jyt0532.com/2020/03/24/dip/
###### tags: `SOLID` `Design Pattern` `OOD`