AI 時代最大的設計轉變,不在於是誰在寫程式碼,而在於這些程式碼預期要活多久。
在軟體領域,程式碼變動一直都不是什麼好詞。多年以前,微軟研究人員就曾指出,相對程式碼變動率可以預測缺陷密度。Adam Tornhill 還寫過一本名為Your Code as a Crime Scene的書,書中把那些經常被修改、又很複雜的檔案視為第一嫌疑犯。GitClear 的研究則預測,AI 助手會讓在程式碼寫出後兩週內被重寫的比例翻倍,並把這解讀為對品質的下行壓力。這種直覺根深柢固:一直變動的程式碼,就是原本寫錯了的程式碼。
但這種直覺來自於一個撰寫程式碼成本很高的世界。耐用性,才是讓你把錢花得值得的方式。當一個功能的成本只是半天,而不是一個衝刺週期,計算方式就反過來了。重寫某些東西,往往比小心翼翼地保留它還便宜,而且這個趨勢只會越來越明顯。
我們一直以建築物來描述軟體:架構、地基、鷹架、承重牆。建築物應該要靜止不動。
我認為程式碼庫正在變得更像花園。更準確地說,是充滿一年生植物的花園。園丁每個季節都會重新種植一年生植物,沒有人會因為番茄植株十月就死掉而說它是技術債。園丁真正的投資,會放在那些不會頻繁更替的部分:土壤、花床、灌溉系統,以及角落裡的橡樹。良好的結構,正是讓重新種植變得便宜的關鍵。
大量變動的程式碼,本質上就是可丟棄的;而可丟棄,並不代表粗糙。它一樣可以做得很好,只是不打算長久存在。一年生植物的品質標準是:它有做好自己的工作、邊界有測試、而且可以被移除,卻不會把周圍的一切都扯爛。
問題在於,我們目前還沒有一個對「高品質變動」的清楚想像。我們對品質的心理模型,和長壽性糾纏在一起。我們會炫耀那些六年來完全沒被碰過的程式碼。所以變動還是會發生,只是以隱性的方式發生,然後落在最方便的地方。
我看了 Forem 過去六個月的變更:563 次提交。變動最多的檔案是 app/models/article.rb,其中有 37 次被修改。
我們的垃圾訊息處理器也名列前茅,有 13 次。這一點我反而很樂見。垃圾訊息就像季節性作物。垃圾訊息發送者的手法不斷改變,我們的程式碼也應該跟著持續變動。
article.rb 才是那棵橡樹。當橡樹每週都被挖起來時,代表新功能因為那裡最容易種下去,而不斷往核心模型裡扎根。這就是結構上的妥協。問題不是變動本身,而是未經規劃地在承重位置發生變動。
以下幾個想法,可以讓變動變得明確,而不是意外發生:
把層次命名清楚。 明講哪些是一年生、哪些是多年生。我們的 AGENTS.md 已經粗略做到了這件事:提醒 AI 助手在核心認證、動態訊息排序與快取管線周圍要謹慎行事。但這不應只是警告標籤,它應該要成為程式碼庫的形狀。
在花床邊緣放上契約。 介面、資料結構、API 規格,以及把行為而非實作釘死的測試,這些都是多年生。它們背後的東西,不論是人還是代理,都可以自由重寫。
讓移除變得便宜。 好的一年生植物的考驗,是你能不能把它拔掉,卻不會影響到花床。如果某個東西本來就是要常常變動,它就不該在所有地方都長出觸鬚。
按層級衡量變動。 快速層的高變動代表健康;慢速層的變動則是警訊。
不管怎樣,變動都一定會發生。AI 已經讓它成為我們大多數作品的預設變化速率。我們可以繼續把它當成症狀,也可以把它當成設計輸入,打造出能讓我們放心重植的結構。
我得承認,我一直比較傾向這樣的觀點:相較於傳統軟體設計觀念所暗示的,變動其實更可以接受。在我的實務經驗裡,我從來不認為避免變動是一件好事。以前我兩邊都能理解,但現在我堅定站在這一邊:變動和我們的程式碼庫與系統品質、剛性,都是正相關的。
我寧願照料花園,也不想假裝它是一棟建築。