規格優先開發(Spec-first-dev)
DDD 命名,BDD 指定,最小變更滿足它們,證據證明它們。與技術棧無關。
1. 先思考後編碼
- 陳述假設。若請求不明確或有多種解讀,則列出它們並提問。切勿默默選擇。
- 若存在更簡單的做法,請提出並反對。
- 讀取任務觸及的程式碼。列出變更必須影響的所有項目(呼叫者、測試、測試用具、設定、匯出)以及可能破壞的項目(資料損毀或外洩、停止運作的呼叫者)。此即範圍;額外功能不包含在內。用一行文字列出跳過的額外功能。
- 在首次編寫前,從主分支建立一個適合該工作的分支(例如
feat/<feature>、fix/<bug>)。唯讀工作無需分支。
2. 對領域進行建模(DDD)
在編碼之前,用幾行文字記錄:
- 限界上下文及其通用語言:領域專家使用的術語。重用程式碼庫中現有的術語;僅在必要時新增。
- 聚合及其不變量:始終必須保持為真的事項。
- 程式碼、測試與訊息中的名稱使用這些術語。拒絕泛用名稱(
handle、process、manager、utils)。 - 領域邏輯是基於純資料的純粹邏輯。I/O(資料庫、網路、時鐘、隨機性)位於邊界的埠(port)後方,並透過注入方式引入。
將其儲存至 docs/specs/<feature>.md。
對於未增加任何領域概念的小幅變更,可跳過此步驟。
3. 指定行為(BDD)
使用領域語言撰寫 Given/When/Then 情境,每個行為一個情境,包含邊界情況與失敗情況。每個情境描述的是可觀察的行為,而非實作。對於不明顯的情境,取得使用者同意;這些情境即合約。將其儲存至 docs/features/<feature>.feature。
4. 規劃
對於多步驟工作,將簡短計畫寫入 docs/plans/<feature>.md:每個步驟都附有驗證檢查。當從現有規格繼續時,仍先撰寫計畫。然後暫停並請使用者審查;在使用者批准前絕不執行。採用第一種能完全運作的選項:
- 它是否必須存在?若否,跳過它。
- 是否已存在於此程式碼庫中?照周圍程式碼的方式使用。
- 標準函式庫或平台功能?使用它。
- 已安裝的依賴項?使用它。絕不要為了幾行程式碼而新增依賴項。
- 一行就能讓讀者一目了然?使用它。
- 否則,使用能運作的最小程式碼。
5. 執行
排程
當您將要執行任務時(無論是否有規格或計畫),請檢查這些任務是否適合:數個可分離的項目(例如 3 個以上的修正)、獨立的步驟,或難度明顯不同的步驟。若是,請在進行第一次編輯前,讀取 orchestration.md(位於此檔案旁)並提供其兩個選項(透過 AskUserQuestion):若您撰寫計畫,則在計畫審查的同一回合中詢問;否則立即詢問。務必詢問;其他任何核准(計畫、規格、「可以」)都不算選擇。若任務不適合,則直接內嵌進行。
紅燈、綠燈、重構,每個情境
- 將情境轉換為失敗的測試。執行它;確認其因正確原因而失敗。
- 撰寫能通過測試的最少程式碼。執行它。
- 僅重構此變更所造成混亂的部分。
- 錯誤修正:先用失敗的情境重現問題,grep 函式的每個呼叫者,在共用程式碼中一次性修正根本原因。
6. 保持差異最小化
- 僅觸及必須修改的部分。比照現有風格;不要改進相鄰的程式碼。每一行變更都必須追溯到請求。
- 僅移除您的變更所產生的孤立程式碼;提及其他死程式碼,但不要刪除它。
- 不要加入任何無人要求的抽象層、包裝器、選項、設定或「留待將來使用」的程式碼。刪除優於新增。
- 移動的程式碼保留其錯誤處理與驗證邏輯。
- 僅用一行註解說明原因。已知限制需加上註解:
shortcut: <限制>, <何時升級>。 - 絕不能刪減:信任邊界的驗證、防止資料遺失的錯誤處理、安全性、無障礙性、使用者要求的任何內容。
7. 先驗證再聲明完成
執行測試以及任何建置或型別檢查。讀取輸出。報告真實結果;若有項目失敗或未執行,請如實說明。不要說「應該可以」。
8. 回覆
以一行或兩行結尾:您跳過或未檢查的項目,以及使用者必須知道的任何風險。