S.O.L.I.D

Single Responsibility Principle 單一職責原則

定義

A class should have only one reason to change

原則

  • 一個類別只負責一個職責
  • 至少要做到interface單一職責,class盡量做到只有一個原因引起變化

Open Closed Principle 開閉原則

定義

Software entities like classes, modules and functions should be open for extension but closed for modifications.

應對擴充開放,對修改封閉,在變更需求或增加功能時,盡量不要修改到原本的程式碼

原則

  • 抽象約束

    • 用介面/抽象類約束擴展,不允許出現在介面/抽象類中不存在的public方法
    • 參數類型、引用對象盡量使用介面/抽象類
    • 抽象層盡量不要修改
  • metadata控制模組行為

  • 封裝變化

from:設計模式之襌

Liskov's Substitution Principle 里氏替換

定義

Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.

"如果你的程式有採用繼承,或是定義了類似 Java 的 interface 然後提供若干個該 interface 的實做(implementation),則在你的系統中,只要是 base types(父類別或是 interfaces)出現的地方,都可以用 subtypes (子類別)或是該 interface 的實做來取代,而不會破壞程式原有的行為" from: 亂談軟體設計(4):Liskov Substitution Principle

原則

  • 子類必須完全實現父類的方法
  • 子類可以有自己的個性(方法和屬性)
  • 覆蓋或實現父類的方法時輸入參數可以被放大
  • 覆寫或實現父類的方法時輪出結果可以被縮小

from:設計模式之襌

Low of Demeter 迪米特法則

定義

一個對象應該對其他對象有最少的了解

原則

  • 只和朋友交流(Only talk to your immediate friends)

在一個類別的方法m中,可以再呼叫的方法應只能來自:類別本身、傳給m的引數、m中建立之物件、C實例擁有之物件。

private A a;

private void f() {...}

public void m(B b) { // 方法中只能呼叫

    f();               // 類別定義的方法

    b.action();        // 引數的方法

    new D().run();     // 自建物件之方法 

    a.execute();       // 實例擁有物件之方法
}

from: 封裝與迪米特法則

  • 朋友間也是有距離的, 盡量不要對外公布太多public方法

Interface Segregation Principle 介面隔離原則

定義

Clients should not be forced to depend upon interfaces that they don't use.

Client不應該依賴它不需要的介面

The dependency of one class to another one should depend on the smallest possible interface.

Class間的依賴關係應該建立在最小的介面上

原則

  • 介面盡量小,但要先滿足單一職則原則
  • 介面要高內聚,public方法盡量少,變動風險才小
  • 訂製服務,單獨為一個客戶提供服務,只提供客戶要的方法
  • 介面設計是有限度的,粒度大小沒有一定標準,開發難度與靈活性要取平衡點

from:設計模式之襌

Dependency Inversion Principle 依賴反轉原則

定義

High level modules should not depend upon low level modules.Both should depend upon abstractions.

Abstractions should not depend upon details.Details should depend upon abstractions.

  • 模組間依賴通過抽象(interface/abstract class)發生,實現類(concrete class)之間不發生直接的依賴關係
  • 接口或抽象類不依賴於實現類
  • 實現類依賴接口或抽象類

from:設計模式之襌

program to an interface, not an implementation

原則

  • 每個類盡量都有介面或抽象類
  • 變量的表面類型盡量是介面或抽象類
  • 任何類都不應該從concrete class派生
  • 盡量不要覆寫基類的方法
  • 結合里氏替換原則使用

from:設計模式之襌

Reference