JavaScript 中的 SOLID 原則(一):“S”代表什麼

一顆小行星發表於2022-04-11

你可能已經瞭解過一些設計原則或者設計模式,本文主要漸進的講解了SOLID原則:

  • 不使用SOLID是怎麼編寫程式碼的,存在什麼問題?
  • 應該使用SOLID中的哪個原則?
  • 使用SOLID我們應該如何對程式碼進行修改?

相信對比和沉浸式的示例會讓你更容易理解SOLID原則,以及如何應用到程式碼實踐中。

這是SOLID的第一篇翻譯文章(原文一共五篇),來自hackernoon,作者是serhiirubets,歡迎持續關注。

在本文中,我們將討論什麼是 SOLID 原則,為什麼我們應該使用他們和如何在JavaScript中使用他們。

什麼是SOLID

SOLID 是 Robert C. Martin 的前五個物件導向設計原則的首字母縮寫詞。這些原則的目的是:讓你的程式碼、架構更具可讀性、可維護性、靈活性。

單一職責原則(Single Responsibility Principle)

S - 單一職責原則 一個實體應該解決一項特定任務。

當我們的類(函式、元件、服務)做很多東西,那就會得到一堆關聯的程式碼,如果改動一處可能會影響到其他地方,這些地方其實沒有相關性。而且這個類很難維護,新增的程式碼改動可能會影響到其他地方,造成不可預知的問題。可讀性也會很差,如果這個檔案程式碼量很大,理解起來會異常痛苦。

我們先來看一下沒有使用單一原則的示例:

class Movie {
  constructor(options){
    this.name = options.name;
    this.description = options.description;
    this.rating = options.rating;
  }
  changeDescription (newDescription) {
    this.description = newDescription;
  }
  changeRat ing (newRating) { 
    this.rating = newRating; 
  }
  saveUserToFile() []
  saveUserToDB() []
} 

我們寫了一個簡單的類Movie,並提供了一個方法來修改描述、評級、儲存電影到資料庫或檔案系統。看上去沒有什麼問題,但是考慮到未來可能新增的擴充套件:

  • 我們可能會新增一些新的方法,比如:從資料庫中獲取一部電影的資料,在儲存電影的時候進行驗證,從資料庫中刪除電影等,我們的類將會是“God Object”反模式(“上帝模式”:一個類做了太多事情,或者把很多不相關的邏輯放到了一個類中來完成)。
  • 我們可能會修改一個方法,很大概率上會影響其他地方。
  • 重複的程式碼。我們可能還有其他的類,比如Audio或Picture,這些類可能也會使用類似的資料庫、檔案系統、和驗證方法,我們應該怎麼做呢?第一個想法可能是在每個類(Audio、Picture、Movie)中去寫同樣的方法,這剛好就是第二個反模式“DRY”(Don't repeat yourself.)。而且如果系統中包括很多類,每個類都有自己的方法,當做調整的時候大概率會忘記修改某個類的邏輯,這就會造成問題。
  • 更難理解和維護。

那麼如何重寫程式碼邏輯來解決這些問題?我們應該先想起使用“單一職責原則”,“單一職責”實際上就是“一個實體解決一個特定的任務”。那在“Movie”類中有什麼任務呢?

  • 處理電影資料
  • 運算元據庫
  • 操作檔案系統

那我們就可以建立3個類:Movie、DB、FileSystem。

class Movie {
    constructor(options) {
        this.name = options.name ;
        this.description = options.description; 
        this.rating = options.rating;
    }
    changeDescription(newDescription) {
        this.description = newDescription;
    }
    changeRat ing (newRating) {
        this.rating = newRating;
    }
}

class DB {
    constructor(options) {
        this.url = options.url;
        this.loginname = options.loginname;
        this.password = options.password;
    }
    save(data) {}
    delete(id) {}
}

class FileSystem {
    constructor(options) {
        this.name = options.name;
    }
    save(data) {}
    delete(data) {}
}

現在我們有了3個獨立的類,每個類只用來完成一個特定的任務。這樣分離有以下好處:

  • DRY原則。我們不需要再重複DB(檔案)的邏輯,可以把任何實體(音樂、圖片)傳遞給DB類,類會將他們儲存到DB。
  • 程式碼可讀性更好,邏輯更簡單。
  • 沒有了“God Object”
歡迎關注微信公眾號"混沌前端"

推薦閱讀:

基於TypeScript理解程式設計的SOLID原則

clean-code-javascript: SOLID

相關文章