圖解你身邊的 SOLID 原則 - JS 實例版

上次筆者翻譯了一篇圖解 SOLID 原則javascript

原文見: 圖解你身邊的 SOLID 原則

過了兩天發現有人爲那篇文章補充了 JavaScript 例子,看了下例子還不錯,此次就順便也翻譯一下哈,部分例子有刪改~java

關於概念部分就很少說了,看上一篇或者看圖就好~ 那麼直接進入正題:數據庫

S - 單一職責原則

1_s.jpg

例子

咱們假設須要驗證一個表單,而後將用戶保存到數據庫中。segmentfault

不推薦api

/**
 * 這個函數的名字就明顯違背了單一職責原則
 * 對於表單的驗證和用戶建立被耦合在一塊兒了
 * 這樣寫是不推薦的!
 */
function validateAndSaveUser (req) {   
  // 調用外部函數來驗證用戶表單
  const isFormValid = validateForm(req.name, req.password, req.email)
  // 若是表單合法
  if (isFormValid) {
    doCreateUser(req.name, req.password, req.email) // 建立用戶的具體實現
  }
}

推薦架構

// 驗證請求的函數
function validateRequest (req) {
  // 調用外部函數來驗證用戶表單
  const isFormValid = validateForm(req.name, req.password, req.email)
  // 若是表單合法
  if (isFormValid) {
    createUser(req) // 在另外一個模塊中實現
  }
}
// 僅僅用來將用戶存儲到數據庫
function createUser (req) {
  doCreateUser(req.name, req.password, req.email) // 具體實現代碼
}

上面的修改雖然看起來很小,可是將驗證邏輯和用戶建立邏輯進行了解耦,而用戶建立貌似是個會常常更改的功能,這就爲未來的修改提供了遍歷。函數

O - 開閉原則

2_o.jpg

例子

假設咱們有如下的權限驗證函數:測試

const roles = ["ADMIN", "USER"]
function checkRole (user) {
  if (roles.includes(user.role)) {
    return true
  }
  return false
}
// 角色校驗
checkRole("ADMIN") // true
checkRole("Savo") // false

若是咱們想要添加一個超級管理員,爲了避免修改以前的代碼(或者說咱們原本就沒法修改遺留代碼),咱們能夠添加一個新增權限函數:this

// 此處的代碼沒法修改!
const roles = ["ADMIN", "USER"]
function checkRole (user) {
  if (roles.includes(user.role)) {
    return true
  }
  return false
}
// 此處的代碼沒法修改!
// 咱們能夠定義一個函數專門用來新增角色
function addRole (role) {
  roles.push(role)
}
// 調用新函數來添加角色
addRole("SUPERUSER")
// 驗證角色
checkRole("ADMIN") // true
checkRole("Savo") // false
checkRole("SUPERUSER") // true

L - 里氏替換原則

3_l.jpg

例子

下面以工程師爲例子,初級工程師其實就能夠被高級工程師替換掉。(沒毛病==)url

class Engineer {
  constructor (coder) {
    this.coder = coder
    this.writeCode = function () {
      console.log("Coding") // 工程師都會寫代碼
    }
  }
  // 初級工程師
  Simple (coder) {
    this.writeCode(coder)
  }
  // 高級工程師
  Pro (coder) {
    this.writeCode(coder)
    console.log("Design Architecture") // 高級工程師還須要設計架構~
  }
}
const a = new Engineer("Savokiss")
a.Simple()
// 輸出:
// Coding
a.Pro()
// 輸出: 
// Coding 
// Design Architecture... 

I - 接口隔離原則

4_i.jpg

例子

不推薦

// 什麼狀況下都進行驗證
class User {
  constructor (username, password) {
    this.initUser(username, password)
  }

  initUser (username, password) {
    this.username = username
    this.password = password
    this.validateUser()
  }

  validateUser () {
    console.log("驗證中...") // 添加驗證邏輯
  }
}
const user = new User("Savokiss", "123456")
console.log(user)
// 驗證中...
// User {
//   validateUser: [Function: validateUser],
//   username: 'Savokiss',
//   password: '123456'
// }

推薦

// 將驗證當作一個可選接口
class User {
  constructor (username, password, validate) {
    this.initUser(username, password, validate)
    if (validate) {
      this.validateUser()
    } else {
      console.log("不須要驗證邏輯")
    }
  }
  
  initUser (username, password, validate) {
    this.username = username
    this.password = password
    this.validate = validate
  }
  
  validateUser () {
    console.log("驗證中...") 
  }
}

// 須要驗證的用戶
console.log(new User("Savokiss", "123456", true))

// 驗證中...
// User {
//   validateUser: [Function: validateUser],
//   username: 'Francesco',
//   password: '123456',
//   validate: true
// }

// 不須要驗證的用戶
console.log(new User("Guest", "guest", false))

// 不須要驗證邏輯
// User {
//   validateUser: [Function: validateUser],
//   username: 'guest',
//   password: 'guest',
//   validate: false
// }

D - 依賴倒置原則

5_d.jpg

例子

不推薦

// http 請求依賴了 setState 函數,即依賴了一個細節
http.get("http://address/api/examples", (res) => {
  this.setState({
    key1: res.value1,
    key2: res.value2,
    key3: res.value3
  })
})

推薦

// http 請求
const httpRequest = (url, state) => {
  http.get(url, (res) => state.setValues(res))
}

// 在另外一個函數中設置狀態
const state = {
  setValues: (res) => {
    this.setState({
      key1: res.value1,
      key2: res.value2,
      key3: res.value3
    })
  }
}
// 請求時,將 state 做爲抽象注入進去
httpRequest("http://address/api/examples", state)

總結

SOLID 原則的主要目標是讓任何軟件都應該更容易更改,而且更易於理解。

SOLID 原則同時也讓你的代碼:

  • 更加易於理解
  • 更加易於擴展,同時減小 bug
  • 隔離抽象和實現
  • 更加易於替換實現
  • 更加易於測試

好啦~ 但願本文對你有幫助~

參考文章


本文首發於公衆號:碼力全開(codingonfire)

本文隨意轉載哈,註明原文連接便可,公號文章轉載聯繫我開白名單就好~

codingonfire.jpg

相關文章
相關標籤/搜索