技術債

技術債務就像財務債務,不清償會拖慢開發速度,增加維護成本。

技術債
Photo by Igor Omilaev / Unsplash

軟體系統容易累積 cruft,也就是內部品質的缺陷,造成系統難以修改和擴展。Ward Cunningham 提出的「技術債」比喻,將 cruft 比擬為財務債務,而新增功能的額外負擔如同支付利息。

假設程式碼庫的模組結構混亂不堪。新增一個功能,在結構清晰的狀況下要花四天,但因為 cruft 拖累,得花六天。這多出的兩天,就是技術債的利息。

我喜歡「技術債」這個比喻,因為它提供思考 cruft 的框架。我可以花五天整理模組結構、清除 cruft,就像償還本金。若只為了單一功能,反而划不來,因為要花九天而非六天。但如果接下來還有兩個類似功能,先清除 cruft 就比較划算。

這聽起來像單純的數字遊戲,任何懂試算表的經理都能算。可惜的是,因為我們 無法衡量生產力,成本難以客觀衡量。我們只能 估算 功能開發時間、估算 清除 cruft 後的效益、估算 清除 cruft 的成本。這些估算的準確度都不高。

因此,最好的方法通常是比照處理財務債務,逐步償還本金。開發第一個功能時,我會多花幾天清除部分 cruft,或許就能將未來擴充功能的利息降低到一天。雖然還是要多花時間,但清除 cruft 能降低未來修改程式碼的成本。這種漸進式改善的好處是,我們自然會花更多時間清除經常修改區域的 cruft,而這些區域正是最需要清除 cruft 的地方。

把這件事看成支付利息還是償還本金,有助於決定要處理哪些 cruft。如果程式碼庫中有個雷區,修改起來很痛苦,但只要不去動它就沒事。只有在必須處理那部分軟體時,才會觸發利息支付(這點跟財務利息不同,因為財務利息會隨著時間產生)。所以,cruft 多但穩定的程式碼區域可以先放著。相反地,高度活躍的區域則要對 cruft 零容忍,因為利息太高,會吃不消。這點很重要,因為當開發人員修改程式碼卻忽略內部品質時,cruft 就會累積,修改越多,cruft 累積的風險就越大。

「技術債」的比喻有時被用來合理化忽略內部品質。理由是,防止 cruft 累積需要時間和精力。如果有急需的新功能,或許先承擔技術債,日後再處理比較好。

但這種分析往往不夠周全,cruft 會立刻產生影響,拖慢急需功能的開發速度。這樣做的團隊就像把信用卡刷爆,交付時間比原本投入心力維持內部品質還要慢。在這裡,這個比喻常會誤導人,因為實際情況和財務貸款的機制不同。承擔技術債務來加速交付,只有在低於 設計耐力假說 的設計收益線時才有效,而團隊通常幾週內就會達到這條線,而不是幾個月。

關於哪些 cruft 該被視為技術債,一直都有爭論。我認為,考量技術債是否刻意產生,以及是審慎或魯莽的,會很有幫助,這讓我想到 技術債務象限

延伸閱讀

據我所知,Ward 最早在 OOPSLA 1992 的經驗報告中提出這個概念。維基 上也有相關討論。Ward 有一段 影片演講,談他創造的這個比喻。

「apenwarr」寫了一篇好文:技術債務比喻的極限主義,探討如何應用這個比喻。他提到:「我真的很喜歡『技術債』這個比喻。很多人不喜歡,但我認為那是因為他們沒有充分延伸這個比喻,或者沒有正確理解財務債務。」

Dave Nicolette 以一個 精彩的案例研究 延伸 Ward 對技術債的觀點,這正是我所謂的 審慎意圖債務

幾位讀者提供了一些好名稱。David Panariti 將寫得不好的程式稱為 赤字程式設計 (deficit programming)。幾年前他開始用這個詞時,正好呼應政府政策;我想現在用也很恰當。

Scott Wood 建議,「技術通膨 指的是當前技術水平超過產品基礎太多,以至於開始與產業脫節。例如,程式語言版本落後太多,導致程式碼與主流編譯器不相容。」

Steve McConnell 指出這個比喻的幾個重點,特別是如何控制非意圖性債務,才能在必要時承擔意圖性債務。我也喜歡他提出的最低付款概念(嵌入式系統比網站的修復成本更高)。

Aaron Erickson 談到 安隆式財務

Henrik Kniberg 認為,舊的技術債才是最大的問題,設定質化的債務上限有助於管理它。

Erik Dietrich 討論 技術債務的人力成本:團隊內鬥、技能退化與人員流失。