變更衛生與程式碼工藝 是做什麼的?
概述
如何塑造變更以及如何撰寫程式碼。兩個主題:將結構性變更與行為性變更分開,以及用最不耍聰明的方式說出你的意圖。
變更衛生
- 結構性變更先於行為性變更,且獨立驗證。 重組(拆分檔案、重新命名、新增註解)是與改變行為(新增限制、修改邏輯)獨立且可分別檢查的步驟。絕不要將它們混在一個不可分割的變更中——審查者無法分辨安全的重新排列與真正的邏輯變更。
- 每次變更改變一件事。 一個變更只有單一且可說明的目的。
- 改善你正在處理的程式碼,當其問題影響你的任務時(讓露營地比來時更乾淨)——但不要開始無關的重構。專注於目標。
程式碼工藝
- 明確優於隱含。 不該用通配符的地方就不要用,不該有隱式轉換,不使用空字串或魔術哨兵。說出你的意圖。
- 描述性命名。 函式/變數名稱說明它們的功能;遵循語言與生態系統的慣例。
- 註解意圖,而非機制。 在非顯而易見時解釋為什麼;對不言自明的程式碼省略註解。
- 小型且單一職責的單元。 對於任何單元,你應該能夠說明它做什麼、如何使用、依賴什麼——而不需閱讀其內部實作。一個大型檔案通常做了太多事。
- 生產程式碼中的 DRY 需謹慎判斷。 重複是信號,而非自動錯誤。第二次出現極相似的程式碼時,需要做出審慎決定:抽象化,或記錄為什麼不抽象。抽象化共享的意義,絕非偶然的形狀——看起來相似但因為不同原因而變化的東西應保持分離。
- 遵循生態系統標準。 使用熟練從業者預期的慣用法與良好支援的函式庫。不要重新發明平台已經解決的問題。
命名的張力
- DRY 與過早抽象化: 生產程式碼僅在已證實的意圖重複上進行抽象,而非預期的形狀重複。不確定時,等待第三次出現(YAGNI 規則主導最終決定)。
- DRY 與 DAMP: 生產程式碼應 DRY;測試程式碼應 DAMP(清晰優於去重,參見
tests-as-a-control)。將 DRY 應用於測試是一種違反。
常見合理化藉口
| 藉口 | 現實 |
|---|---|
| 「我會在同一個提交中重新命名並新增功能」 | 結構與行為混在同一個 diff 中是無法審查的。分開它們。 |
| 「兩份拷貝,我必須立刻 DRY 化」 | 第二次出現 = 做決定。相同形狀 ≠ 相同意義。偶然的重複應保持分離。 |
| 「既然來了,讓我把這個其他模組也重構一下」 | 無關的重構會擴大範圍與風險。記下來;現在不要做。 |
| 「巧妙的單行更優雅」 | 明確勝過聰明。為下一位閱讀者最佳化。 |
紅旗 — 停下來
- 一個 diff 既移動程式碼又改變其行為
- 一個 PR 的目的需要用「與」來描述
- 在第一次看到相似性時就抽象化,或基於預期(而非實際)的重複
- 一個你再也無法記在腦中的檔案
完整理由:憲法的第 V 條與第 VI 條,收錄在 engineering-constitution/references/engineering-constitution.md。