看到「87 倍行數落差」「92% 死碼」這種數字,很自然會懷疑:這是不是刻意做出一個極端案例,用來製造戲劇效果?真實世界的過度設計,會有這麼誇張嗎?
我想老實回答:是的,這是我刻意做出來的示範案例,但刻意的地方不是「灌水製造效果」,而是刻意控制業務複雜度極簡單、刻意讓兩個版本共用同一組一字未改的驗收測試——目的正是要排除「業務本來就複雜」這個變數,讓兩個版本唯一的差異只剩下「寫法」。今天就把這個案例的設計方式講清楚,讓接下來幾天的拆解有一個扎實的地基。
ai-news-test(recca0120/ai-news-test)這個示範專案的整體設計方式main 與 over-engineered-demo)分別是用什麼方式產生的做這個案例最重要的一個決定,是刻意選一個業務邏輯極簡單的題目——一個新聞發佈系統,只有草稿、發佈、下架、編輯限制、列表查詢這幾個動作,核心規則只有 4 條:
選一個簡單題目,不是因為簡單題目比較好寫,而是要排除「業務複雜度不同」這個變數。如果拿兩個業務規則本來就不一樣的系統來比較,行數跟檔案數的差異可能真的只是反映了業務本身的差異,沒有辦法拿來說明「寫法造成的差異」。控制業務邏輯簡單、固定,才能讓後面的數字對照有意義。
案例設計的第二個核心決定,是用驗收測試(Given-When-Then 形式,共 10 個測試案例,寫在 tests/Feature/PublishArticleTest.php)當作兩個版本共同的「行為契約」,而且從頭到尾一行都沒有改過。
這個設計的用意,是讓「兩個版本行為完全相同」這件事不是靠事後檢查、靠人工比對確認的,而是靠同一份測試強制保證的——只要兩個版本都通過同一組測試,就代表它們在驗收測試涵蓋的範圍內行為一致。這樣一來,剩下的所有差異(檔案數、行數、架構複雜度)就只能來自「怎麼寫」,而不是「做了不一樣的事」。這也是本系列第 3 天強調過的重點的另一面:測試是行為契約,兩個版本行為契約相同,不代表設計契約相同——這個案例正是用來具體展示這個落差。
main branch:用 Outside-In TDD/ATDD 的方式,從 10 個驗收測試出發,一步步往內建立「測試逼出來的」類別,沒有先畫架構藍圖再回頭補測試。這個版本的原則是:如果一段程式碼不是被某個測試逼出來的,它就不應該存在。 最終結果是 3 個檔案、249 行。over-engineered-demo branch:從同一組驗收測試出發,但刻意模擬「AI 拿到一句模糊需求後自由發揮」會產生的樣子——不限制自己只寫測試逼出的東西,而是用常見的專業架構模式(Domain Aggregate、CQRS 的 Command/Query/Handler/Bus、多層 Repository 裝飾器、Specification Pattern、Event-Driven 機制)把整個系統包裝起來,同時預先建好各種「未來可能需要」的功能與欄位。最終結果是 745 個檔案、21,727 行,同樣通過那 10 個一字未改的驗收測試。這個設計最重要的價值,是把「同一份需求,兩種寫法」這件事變成一個可以重現、可以驗證的對照組,而不是一個口耳相傳的印象或個案抱怨。任何人都可以實際 clone 這個 repo、切換兩個 branch、跑一次測試,親眼確認「兩者確實都通過同一組測試」,而不需要相信我口頭轉述的數字。
這正是本系列想強調的東西:與其空談「AI 容易過度設計」這種印象式的說法,不如做出一個可以重現的具體案例,讓抽象的論點有紮實的證據支撐。 這也呼應本系列的主題句:AI 沒有發明過度設計,它只是讓過度設計的速度追上了你按下 Enter 的速度;Review 要跟得上,審的就不能再是程式碼本身,而是產生程式碼的規則。 而這個案例,正是想具體示範「速度差多少」跟「差在哪裡」。
main 版本的 3 個檔案長什麼樣,Outside-In TDD 怎麼一步步逼出這個結果over-engineered-demo 版本自由發揮出的架構全貌如果讓你現在去 review over-engineered-demo 這個版本的一個 PR(假設它是一次性提交,而不是像現在這樣拆成 745 個檔案攤在你面前),你覺得自己在多短的時間內,能不能發現「92% 的程式碼從未被呼叫過」這件事?
ai-news-test 案例刻意選擇業務邏輯極簡單的題目,目的是排除「業務複雜度不同」這個變數main 版本用 Outside-In TDD 只建立測試逼出的類別,over-engineered-demo 版本模擬 AI 自由發揮,用專業架構模式包裝並預先建好假設性功能Day 9 要具體攤開 main 版本的 3 個檔案,看 Outside-In TDD/ATDD 是怎麼從 10 個驗收測試,一步步逼出這個乾淨結果的。
做這個案例的過程中,我自己最大的收穫其實不是「證明了 AI 容易過度設計」——這件事我早就在真實工作中隱約感覺到了。真正的收穫是把一個模糊的印象,變成一個可以重複驗證、可以指著具體數字說話的東西。以前跟同事討論「這個系統是不是設計得太複雜」,常常變成各自憑經驗各說各話;現在至少可以指著「業務規則沒變、行數差 87 倍」這種具體對照,讓討論有一個雙方都認的基準線,而不是比誰的架構品味比較高明。