»

SOLID principles

Coding, Design — Tags: , — Posted by Starck on October 1, 2013


The SOLID design principles, articulated by Robert “Uncle Bob” Martin, are five principles that provide a good foundation for sound application design. The five principles are:

  • S (Single Responsibility Principle)
  • O (Open/Closed Principle)
  • L (Liskov Substitution Principle)
  • I (Interface Segregation Principle)
  • D (Dependency Inversion Principle)


Single Responsibility Principle

A class (or unit of code) should have one responsibility.

設計一個類別,所有的實作應只為用來解決一個特定意圖(需求) 而如果為了解決這個需求,而延伸出其它的需求與實作,應該把這些工作交給其它類別。


Open/Closed Principle

A class should be open for extension but closed for modification. You can extend a class or implement and interface, but you should not be able to modify a class directly. This means you should extend a class and use the new extension rather than change a class directly. Additionally, this means setting class attributes and methods as private or protected properly so they cannot be modified by external code.

一個類別應能被很有彈性地擴充,而不是直接修改其自身來解決新的意圖(需求)。以此原則來決定這個類別的屬性和方法該怎麼被限制,或該開放什麼?

ValidationModel


Liskov Substitution Principle

Objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program. In PHP, this often means creating interfaces for your code to implement. You can then change (switch-out) implementations of the interfaces, Doing so should be possible without having to change how your application code interacts with the implementation. The interface serves as a contract, guaranteeing that certain methods will be available.

每當我們在一個類別引用了其它類別時,多思考如何往後如何切換或取代這件事,之後如果不用到它,會有什麼影響?如何讓更換這件事不費力? 經驗上,我們往往會遇到一些被設計用來解決相同需求(購物這個需求),但有各自實作方式(Paypal, Stripe …等支付方法)的情況,我們可以利用界面(interface),定義一個大家共同遵循的規範(我們都應該有購買這個行為),這個概念如同讓這些類別簽定了一個契約(Contract),以確保都將一定會實行哪些行為。如此,我們只要專注那些行為在流程上的安排,不管現在這個實行的對象為何都不致於讓流程出錯,甚致隨時可以將其取代成別的也簽定契約的類別。

LiskovSubstitution


Interface Segregation Principle

Many client-specific interfaces are better than one general-purpose interface. In general, it’s preferable to create an interface and implement it many times over than create a general-purpose class which attempts to work in all situations.

因為在程式語言中,一旦行為(method)在界面(interface)中被定義,在類別中就要嚴格地去實作。所以應該避免用一個很概廓性的界面讓類別去實作很多不必要的行為。 就設計的角度來看,就是思考如何拆分行為的關連性這件事。


Dependency Inversion Principle

One should depend upon abstractions rather than concrete classes. You should define class dependencies as an interface rather than a concrete class. This allows you to switch an implementation of the interface out without having to change the class using the dependency.

This principle states that high-level code should not depend on low-level code, and that abstractions should not depend upon details.

依賴界面的關係比依賴類別來得更好,目的是希望在一個系統中元件之間相互依賴的程度(耦合性)盡可能的降低,以避免牽一髮動全身的情況發生。 以這個原則來說,最常見的情況,就是該怎麼設計如何切換資料來源的機制。資料的存取可能是在 MySQL, NoSQL, 甚至是 Memory,我們如何在不影響主程式太多的情況下改變來源?

舉例來說

這段程式大概是長得像這樣的句子:

「我要去MySQL檔案庫查詢使用者名單」。

這是一個耦合性高的句子,意即我們想要稍微改變一下行為,整個「」裡的文字都要變動,所以我們稍微調整一下:

我要去 MySQL 檔案庫「查詢使用者名單」。

MySQL 檔案庫為 來源地, 而 查詢使用者名單 為動作。

雖然我把來源地區隔開來,但實際上如果我改去 NoSQL 檔案庫,那麼這個句子還是會出錯,因為我們明確指出我們要到 MySql 檔案庫,該用什麼句子來表達才不會有問題呢?

答案是使用統稱:「我」要去「檔案庫」「查詢使用者名單」。

白話一點就是叫我們講話講得愈模糊愈好,就像是如果我跟一個以上的女朋友同時在交往,每一位打電話來我都叫她「親愛的」,這樣就可以避免叫錯人的情況啦。





(c) 2024 Starck Lin | powered by WordPress