1:單一職責原則(SRP):
一個優良的系統設計,強調模組間保持低耦合、高內聚的關係,在物件導向設計中這條規則同樣適用,所以物件導向的第一個設計原則就是:單一職責原則(SRP,Single Responsibility Principle)。
單一職責,強調的是職責的分離,在某種程度上對職責的理解,構成了不同類之間耦合關係的設計關鍵,因此單一職責原則或多或少成為設計過程中一個必須考慮的基礎性原則。
關於單一職責原則,其核心的思想是:
一個類,最好只做一件事,只有一個引起它變化的原因。
單一職責原則可以看作是低耦合、高內聚在物件導向原則上的引申,將職責定義為引起變化的原因,以提高內聚性來減少引起變化的原因。職責過多,可能引起它變化的原因就越多,這將導致職責依賴,相互之間就產生影響,從而極大的損傷其內聚性和耦合度。單一職責,通常意味著單一的功能,因此不要為類實現過多的功能點,以保證實體只有一個引起它變化的原因。
因此,SRP原則的核心就是要求對類的改變只能是一個,對於違反這一原則的類應該進行重構,例如以Façade模式或Proxy模式分離職責,通過基本的方法Extract Interface、Extract Class和Extract Method進行梳理。
2:開放-封閉原則(OCP)
無論如何,開放封閉原則(OCP,Open Closed Principle)都是所有物件導向原則的核心。軟體設計本身所追求的目標就是封裝變化、降低耦合,而開放封閉原則正是對這一目標的最直接體現。其他的設計原則,很多時候是為實現這一目標服務的,例如以Liskov替換原則實現最佳的、正確的繼承層次,就能保證不會違反開放封閉原則。
關於開發封閉原則,其核心的思想是:
軟體實體應該是可擴充,而不可修改的。也就是說,對擴充是開放的,而對修改是封閉的。
因此,開放封閉原則主要體現在兩個方面:
對擴充開放,意味著有新的需求或變化時,可以對現有代碼進行擴充,以適應新的情況。
對修改封閉,意味著類一旦設計完成,就可以獨立完成其工作,而不要對類進行任何修改。
“需求總是變化”、“世界上沒有一個軟體是不變的”,這些言論是對軟體需求最經典的表白。從中透射出一個關鍵的意思就是,對於軟體設計者來說,必須在不需要對原有的系統進行修改的情況下,實現靈活的系統擴充。而如何能做到這一點呢?
只有依賴於抽象。實現開放封閉的核心思想就是對抽象編程,而不對具體編程,因為抽象相對穩定。讓類依賴於固定的抽象,所以對修改就是封閉的;而通過物件導向的繼承和對多態機制,可以實現對抽象體的繼承,通過覆寫其方法來改變固有行為,實現新的擴充方法,所以對於擴充就是開放的。這是實施開放封閉原則的基本思路,同時這種機制是建立在兩個基本的設計原則的基礎上,這就是Liskov替換原則和合成/彙總複用原則。關於這兩個原則,我們在本書的其他部分都有相應的論述,在應用反思部分將有深入的討論。
對於違反這一原則的類,必須進行重構來改善,常用於實現的設計模式主要有Template Method模式和Strategy模式。而封裝變化,是實現這一原則的重要手段,將經常發生變化的狀態封裝為一個類。
3:裡氏代換原則(LSP)