如果你把一個「文章加一個分類欄位」的需求丟給團隊,PR 開回來改了 11 個檔案,你會核准嗎?大部分 reviewer 的反應可能是掃過一遍,覺得「架構滿完整的」,然後按下 Approve——因為沒有一個明確的基準,能讓你說出「這樣算多還是算少」。
今天要解決的正是這個「沒有基準」的問題。我會用這系列案例裡真實量測過的數字,示範怎麼建立一個具體、可比較的複雜度預算:新增一個欄位,改動檔案數到底該落在哪個範圍。
這系列的案例專案 ai-news-test 有兩個版本:main(Outside-In TDD 寫出的乾淨版本,3 個檔案、249 行)跟 over-engineered-demo(同一組驗收測試、AI 自由發揮的過度設計版本,745 個檔案、21,727 行,但真正會被入口點呼叫到、參與實際邏輯的只有其中 62 個檔案)。
假設要新增一個真實但小的需求:文章加上「分類」欄位。兩個版本需要碰的檔案數:
| 版本 | 需要碰的檔案 | 檔案數 |
|---|---|---|
main(乾淨版) |
Article.php(建構子+getter)、ArticleRepository.php(SQL 與 mapping)、PublishArticleService.php(方法簽名) |
3 |
over-engineered-demo(僅計有被呼叫的 62 個檔案內) |
ArticleAggregate、ArticleTableGateway、ArticleSqlBuilder、ArticleRowToAggregateMapper、CreateArticleCommand/Handler/Validator、EditArticleCommand/Handler/Validator、PublishArticleService |
約 10-11 |
需求本身的複雜度沒有變——多一個欄位,就是多一個欄位,但改動檔案數在過度設計版本裡是乾淨版本的 3-4 倍。這組數字,比「這個系統總共有幾行程式碼」更能回答一個 reviewer 真正該問的問題:當需求只增加了一點點,程式碼要跟著增加多少,才算合理?
行數這個指標有個問題:它容易被程式碼風格(縮排、空行、單行 vs 多行寫法)干擾,而且「一行程式碼」在不同抽象層代表的意義差很多。改動檔案數則更直接地反映了「這個需求牽動了多少個獨立的職責」——每多一個要改的檔案,通常意味著多了一層要理解、要協調、要確保沒有遺漏的地方。
這正是這個系列主題句在日常 review 裡最容易落地的一個具體規則:AI 沒有發明過度設計,它只是讓過度設計的速度追上了你按下 Enter 的速度;Review 要跟得上,審的就不能再是程式碼本身,而是產生程式碼的規則。 落到日常操作上,就不能再靠「看起來多不多」的直覺,而要有一個訂在前面、可以拿出來對照的複雜度預算。
複雜度預算最容易被誤用的方式,是把它當成一條放諸四海皆準的鐵律——例如「任何 PR 改動檔案數不能超過 5 個」。這是錯的,因為不同類型的需求本來就該對應不同的改動範圍:新增一個欄位跟新增一個全新的業務流程,合理的改動範圍天差地遠。複雜度預算該綁定的是「需求的類型」,而不是一個放諸四海皆準的絕對數字。
❌ 誤用:用一個固定數字套用所有 PR
規則:任何 PR 改動檔案數不得超過 5 個
問題:新增一個全新業務流程本來就需要碰多個檔案,
這條規則會逼工程師把該分開的職責硬塞進同一個檔案
✅ 正確做法:依需求類型分級,事先訂出合理區間
需求類型:既有實體新增一個純資料欄位(無新業務規則)
複雜度預算:3-5 個檔案(實體本身、持久化層、對外介面簽名)
需求類型:新增一條業務規則(例如新的狀態轉換限制)
複雜度預算:視規則影響的協作物件數量另訂,
但要在 PR 描述裡先寫下「預期改動範圍」,
實際改動超出預期時要能講出理由
訂出這個區間之後,PR 描述裡就可以直接寫「這是一個新增欄位型的需求,預期改動 3-5 個檔案,實際改了 11 個,多出來的部分是因為……」——把「這樣算多嗎」這個模糊的直覺判斷,變成一個可以被質疑、被回答的具體數字,這也是 Review 分工模型裡「人定規則」最基本的一步:規則不需要多複雜,先把「合理範圍」講清楚,就已經比什麼都沒有好上太多。
如果你現在要幫自己的專案訂一條複雜度預算,你會先從哪一種需求類型開始(新增欄位?新增業務規則?新增一個外部整合?)?你估計的合理改動檔案數會是多少,你有信心這個數字經得起下一個 PR 的檢驗嗎?
Day 21 要往前推一步:與其等 AI 寫完再用複雜度預算事後檢查,能不能讓 AI 自己先跑一次 Outside-In 流程,從一開始就把改動範圍限制在合理區間內?
我自己以前review PR的時候,看到改動檔案數比預期多,通常只會在心裡嘀咕一句「怎麼改這麼多」,然後多花點時間看仔細一點,很少真的講出「這樣不合理」的具體理由——因為我自己也講不出一個明確的基準。這次為了寫這篇文章,真的把兩個版本「加一個欄位」的改動都動手算過一次,我才發現:「講不出具體理由」不代表這個直覺是錯的,只代表我一直沒有把它量化成一個可以拿出來討論的數字。這件事一旦做了,以後 review 的底氣完全不一樣。