程式碼整潔之道的 7 個方法

削微寒發表於2020-12-09

原文地址:Clean up your code by applying these 7 rules ⚡️

原文作者:Joachim Zeelmaekers

譯者 & 校正:HelloGitHub-小魚乾 & HelloGitHub-鴨鴨

可讀的程式碼是可維護的

在這篇短文中,我將介紹一些你可以用來改進你的程式碼的方法。本文程式碼示例均使用 JavaScript。

我發現但凡是可讀的程式碼必定是可維護的。

作為一名開發人員,我的目標是編寫高質量的程式碼。團隊中的每個開發人員,不管他/她的技術水平如何,都必須能夠通過閱讀理解我所寫的程式碼。程式碼的可讀性有助於年輕的開發人員編寫程式碼時更加自信。

刪除 不必要的 程式碼註釋

當然,有些程式碼可以非常複雜。我深知這一點且見過很多次。在複雜的程式碼中,我會寫些適當的文件和程式碼註釋。

別誤會。我不是程式碼註釋或 JavaScript JSdoc 的愛好者,而且基本上我能不用它們便不用。

我不需要任何註釋來解釋這個接收 X 個陣列並將它們合併到一個新的陣列中的函式。

function mergeArrays(...arrays) {
  let mergedArray = []

  arrays.forEach(array => {
      mergedArray = [...mergedArray, ...array]
  })

  return mergedArray
}

像示例程式碼,如果增添文件並不能提高可讀性。我希望團隊成員知道展開操作符是什麼。如果他們不清楚,他們應該在程式碼審查 code review 時來問我。

當然,我們不要忘記註釋的程式碼塊。如果我們忘記了,這裡只有一個解決方案:刪除程式碼。既然了不起的 git 可以檢出舊程式碼,那麼為什麼還要把它留在註釋中呢?

請停止把你的程式碼庫變成垃圾場。

重視命名

如果你看到函式名 mergeArrays,就應該很清楚地知道這是一個將 X 個陣列組合成一個新的陣列的函式。

我知道命名是件難事。函式越複雜,命名就越難… 我有個法子讓命名更容易,舉個例子:有一個函式,它會合並兩個陣列並生成一個新的唯一的數字列表。你會怎麼命名?是下面這樣嗎?

function mergeNumberListIntoUniqueList(listOne, listTwo) {
  return [...new Set([...listOne, ...listTwo])]
}

mergeNumberListIntoUniqueList 這個名字並沒有那麼糟糕,至少功能如其名。命名的難點在於這個函式要做兩件事:一個函式做的事情越多,命名它就越困難。將這個函式拆分為兩個單獨的函式,命名會更容易且函式複用更容易。

function mergeLists(listOne, listTwo) {
  return [...listOne, ...listTwo]
}

function createUniqueList(list) {
  return [...new Set(list)]
}

當然,不需要呼叫新函式就可以很容易地建立美觀的一行程式碼。但有時,一行程式碼的可讀性並不高。

If 語句

我對這個問題的命名無力… 看!命名不易…

但我經常看到這種情況。

問題

if(value === 'duck' || value === 'dog' || value === 'cat') {
  // ...
}

解決方法

const options = ['duck', 'dog', 'cat'];
if (options.includes(value)) {
  // ...
}

這樣做,你建立了一段像是英語句子般的可讀程式碼。

如果選項包含值,那麼 ...

提前退出機制

這個準則有很多種命名方式,但我選擇了 “提前退出 Early exit” 這個名字。

讓我給你們看一段程式碼。我相信你們以前見過這樣的東西。

function handleEvent(event) {
  if (event) {
    const target = event.target;
    if (target) {
      // Your awesome piece of code that uses target
    }
  }
}

來我們檢查下物件 event 是否為真,以及屬性 target 是否可用。問題是上面程式碼我們已經用了兩個 if 語句。

讓我們看看如何在這裡實現 “提前退出”。

function handleEvent(event) {
  if (!event || !event.target) {
    return;
  }
  // Your awesome piece of code that uses target
}

在這裡用 “提前退出”,你可以檢查是否 eventevent.target 同時非假 。很明顯,我們確信這一事件 event.target 非假。因為如果這個語句為假,程式就不會執行其他程式碼。

解構賦值

在 JavaScript 中,我們可以解構資料和物件。

根據 developer.mozilla.org 上的文件,解構賦值語法是一種 JavaScript 表示式。通過解構賦值,可以將值從陣列、屬性從物件中取出,賦值給其他變數

一些程式碼示例

// Destructuring an object
const numbers = {one: 1, two: 2};
const {one, two} = numbers;
console.log(one); // 1
console.log(two); // 2

// Destructuring an array
const numbers = [1, 2, 3, 4, 5];
const [one, two] = numbers;
console.log(one); // 1
console.log(two); // 2

解構的問題在於,它有時會為屬性建立一個不好的命名。最好的例子是從 API 獲取資料並接收具有 data 屬性的響應物件。

const url = "http://localhost:8080/api/v1/organizers/1"
const response = await axios.get(url)
const {name} = response.data

這個程式碼示例說明你正在獲取 id 為 1 的 organizer。organizer 物件有一個名字,你可以解構它。這樣做沒什麼問題。

這段程式碼可以正常執行。但是為什麼屬性名還是 name? 那將是整個範圍中唯一的 name 屬性嗎?屬性名又來自哪個物件?

通過重新命名屬性可避免這些問題。

const url = "http://localhost:8080/api/v1/organizers/1"
const response = await axios.get(url)
const {name: organizerName} = response.data

這段程式碼變得更具可讀性。每個人都知道變數是 organizer 的名字。

童子軍規則

聽過這樣一句話嗎:“永遠保持離開時的露營地比你發現它時更整潔”?

這就是童子軍的規則。讓程式碼比發現時更好。你發現程式碼異味 code smell?重構它!你發現一個未使用的變數?刪除它!

我喜歡把童子軍規則和打掃房間的情況進行類比。想象一下,你家裡的每個人都把盤子放在水槽上,把所有垃圾都放在走廊上,把所有要洗的衣服都放在浴室裡。但是每個星期天,你必須花費 4 個多小時清理整個房子。你會鐘意嗎?

我肯定答案是 NO。所以如果每個人都立即清理房間的小部分,星期天的工作量會小一些。

程式碼庫同理。如果每個小的程式碼異味 code smell 都留在程式碼庫中,沒有人刪除未使用的變數,linter 就會抓狂且有大約 77 個 warning。而且程式碼庫將會有很多清潔工作要做,但是如果每個人都承擔起自己的責任並遵守童子軍法則,很多問題將會得到解決。

程式碼風格

同樣重要的還有確定團隊中的程式碼風格。

我不 care 你是喜歡單引號還是雙引號,空格還是 tab,結尾逗號還是不用。選擇一種風格並堅持下去。你可以用 Linter 或者 Prettier 來做這件事。

有很多工具可以用來解決程式碼風格問題。我最鐘意的是使用 Husky 預提交鉤子。Prettier 的文件中也有一個關於預提交鉤子的頁面。

這個預提交鉤子總是在每次提交之前執行配置好的命令。如果你正確地配置它,它會執行得更漂亮,並對所有檔案應用所有規則。這確保了團隊總是擁有統一的程式碼風格,而沒有任何糟糕的程式碼。

小結

我知道有些方法顯而易見,有些則不是。但作為一名全職開發人員,我在不同的程式碼庫上工作。這些規則的重要性只有在較大的程式碼庫中才會突顯。但這並不意味著你不應該將這些方法用在小專案中,提高你的程式碼質量讓小專案更高效。它讓團隊成員方便地閱讀你的程式碼併合並你的 pull 請求。正如我所說的,可讀的程式碼更容易維護,當然可讀的程式碼還有其他更多的好處。

如果你想了解更多關於程式碼整潔之道的知識,可以嘗試閱讀羅伯特・馬丁的《程式碼整潔之道》。

最後,歡迎優秀的你加入 HelloGitHub 的「譯文亦舞」系列,讓你的才華舞動起來!把優秀的文章分享給更多的人。要求:

  • 平時瀏覽 GitHub、開源、程式設計、程式設計師等英文資訊和文章
  • 想把自己閱讀到優秀的英文文章分享給更多的人
  • 翻譯準確但不是直翻或機翻
  • 保證每月至少翻譯或校正 1 篇高質量文章
  • 瞭解 Markdown 和排版規則
  • 聯絡我(備註:翻譯和從那個平臺來的)

封面圖來自 Unsplash 由 Kevin Ku 拍攝

相關文章