Skip to main content

設計原則

如果說設計模式是物件導向程式設計的程式設計思維,那麼設計原則就是程式設計思維的指導總綱。

SOLID原則

  • SRP (Single Responsibility Principle) 單一職責原則
  • OCP (Open-Closed Principle) 開放-封閉原則
    1. 對於擴展是開放的 — 當需求變更時模組行為可以新增的
    2. 對於修改是封閉的 — 當進行擴展時,不需修改既有的程式碼
  • LSP (Liskov Substitution Principle) 里(裡)氏替換原則
  • DIP (Dependency-Inversion Principle) 依賴反轉原則
  • ISP (Interface Segregation Principle) 介面隔離原則

SRP (Single Responsibility Principle)

核心思維:

A class should have only one reason to change. 一個類別應該有且僅有一個原因引起他的變更。

簡單來說: 一個類別只負責一個功能或一類別相似的功能。

優點:

  1. 功能單一,職責清晰。
  2. 增強可讀性,方便維護。

缺點:

  1. 拆分得太詳細,類別的數量會急劇增加。
  2. 職責的度量沒有統一的標準,需要根據專案實現情況而定。

總結:

實現類別要職責單一。

用於指導類別的設計,增加一個類別時使用單一職責原則來核對該類別的設計是否純粹乾淨。也就是讓一個類別的功能盡可能單一,不要想著一個類別包攬所有功能。

OCP (Open-Closed Principle)

核心思維:

Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification. 軟體實體(如類別、模組、函數等)應該對拓展開放,對修改封閉。

簡單來說: 在增加一個功能時,應當盡可能地不去改動已有的程式碼; 當修改一個模組時不應該影響到其他模組。

總結:

要對擴展開放,對修改封閉。

開放封閉原則可以說是整個設計的最終目標和原則!開放封閉原則是總綱,其他四個原則是對這個原則的具體解釋。

LSP (Liskov Substitution Principle)

核心思維:

Functions that use pointers to base classes must be able to use objects of derived classes without knowing it. 所有能引用基類別的地方必須能透明地使用棋子類別的物件。

簡單來說: 只要父類別能出現的地方子類別就能出現(就可以用子類別來替換它)。反之,子類別能出現的地方父類別不一定能出現(子類別擁有父類別的所有屬性和行為,但子類別拓展了更多的功能)。

總結:

不要破壞繼承體系。

用於指導類別繼承的設計,設計類別之間的繼承關係時,使用裡氏替換原則來判斷這種繼承關係是否合理。只要父類別能出現的地方子類別就能出現(就可以用子類別來替換它),反之則不一定。

DIP (Dependency-Inversion Principle)

核心思維:

High level modules should not depend on low level modules; both should depend on abstractions. Abstractions should not depend on details. Details should depend upon abstractions. 高層模組不應該依賴低層模組,二者都該依賴其抽象。抽象不應該依賴細節,細節應該依賴抽象。

高層模組就是呼叫端,而低層模組就是具體實現類別。

抽象就是指介面或抽象類別,細節是指具體的實現類別。

簡單來說: 把具有相同特徵或相類功能的類別,抽象成介面或抽象類別,讓具體的實現類別繼承這個抽象類別(或實現對應的介面)。抽象類別(介面)負責定義統一的方法,實現類別負責具體功能的實現。

總結:

要面向介面程式設計。

用於指導如何抽象,即要依賴抽象和介面程式設計,不要依賴具體的實現。

ISP (Interface Segregation Principle)

核心思維:

Clients should not be forced to depend upon interfaces that they don't use. Instead of one fat interface many small interfaces are preferred based on groups of methods, each one serving one submodule. 用戶端不清該依賴它不需要的介面。用多個細細微性的介面來替代由多個方法組成的複雜介面,每一個介面服務於一個子模組。

簡單來說:

建立單一個介面,不要建立龐大臃腫的介面,盡量細化介面,介面中的方法盡量少。也就是說,我們要為不同類別的類建立專用的介面,而不要試圖建立一個很龐大的接口供所有依賴它的類別呼叫。

介面盡量小,但要有限度。 當發現一個介面過於臃腫時,就要對介面進行拆分。但是如果介面過小,則會造成介面數量過多,使設計複雜化。所以介面大小一定要適度。

優點:

  1. 提高程式設計的靈活性。 將介面進行細分後,多個介面可自由發展,互不干擾。
  2. 提高內聚,減少對外交互。 使介面用最少的方法去完成最多的事情。
  3. 為依賴介面的類別定制服務。 只暴露給呼叫的類別需要的方法,不需要的方法則隱藏起來。

總結:

設計介面的時候要精簡單一。

用於指導介面的設計,當發現一個介面過於臃腫時,就要對這個介面進行適當的拆分。

note

內容來源: Python 設計模式 書籍