選單

寫給架構師的技術債“償還”指南

作者 | Kurt Bittner, Pierre Pureur

譯者 | 馬可薇

策劃 | 丁曉昀

技術債務的類別

技術債務是軟體開發中用於比喻短期決定促使長期成本增加的現象,其中成本的增加類似於隨時間增長的應計利息。更確切地說,團隊當前為某個決定付出的工作越多,後期就越可能需要更高的工作量來糾正這個決定。

這一術語在軟體行業內獲得了不少的關注,但技術債務不是百害無一利的,它有時也能快速解決產品上市的問題。這個概念最早是由 Ward Cunningham 提出的:

第一次交付的程式碼如同欠債一樣,只要能透過重寫還清,一點債務就能加速程序……但如果債務沒有即時還清,那麼就危險了。在問題程式碼上花費的每一分鐘都會算作是債務的利息。地基不牢的實現所帶來的債務負擔甚至會讓全部工程團隊停滯不前,無論這種實現是否是面向物件的。

【注 1】

有兩個重要的點需要注意。首先,技術債務往往是軟體交付過程中很有幫助的權宜之計。沒有任何產品時完美的,無數軟體專案都曾過於沉迷“打磨”短期內完全夠用的程式碼而就此消失。第二點則是,在長期可支援性面前,這些權宜之計可能會需要重新考量。

不過,我們還需要對“技術債務”這一詞有明確定義才能避免引起混淆。Kruchten、Nord 及 Ozkaya 在他們的《管理技術債務》一書中,對技術債務的概念及相應管理方法做了很好的概述,這是他們給出的定義:

在軟體密集型的系統中,技術債務由設計和實現結構組成,這些短期內的權宜之計構建的技術環境,可能讓未來的變動更加昂貴或不可能。技術債務是一種或有負債,主要影響內部系統質量,但不限於可維護性和可進化性。

【注 2】

這種定義深得我們喜愛,因為它更側重於技術債務的影響,而非是其在金融債務方面的比喻,後者僅僅涵蓋了部分問題所在。正如《實踐中的持續架構》所言:

對可維護性和可進化性的關注對技術債務的

對可維護性和可進化性的關注度是影響技術債務看法的關鍵。這就意味著,如果系統沒有對進化的期望,那麼對技術債務的關注也應當是最小化的。以旅行者號航天器為例,其軟體的技術債務是非常有限的,因為它沒有進化的需求,維護的機會也有限。

感興趣的讀者可以參閱注 2 中的《管理技術債務》,以獲取關於該主題的更多內容。也可以在《管理技術債務》、《技術債務》,《技術債務和利息的實證模型》的參考文獻部分,以及 雷曼法,找到更多關於技術債務的實證研究。

什麼是技術債務?

依據 Kruchten、Nord 及 Ozkaya 的定義,技術債務可以分為以下三大類。

架構:

由軟體開發過程中的架構決策造成的債務。

程式碼

:難以維護或發展的臨時程式碼。

生產基礎設施

:為構建、測試和部署軟體系統的基礎設施和程式碼的決策。

此外,技術債務可以是無意為之,也可以是特意為之。許多業界人士認為潛在的缺陷是技術債務的一部分,而架構決策則幾乎永遠是在兩個相互衝突的 QAR 之間權衡,因此後者是屬於“有意為之”的分類。

技術債務一詞的不足

每個術語都有不足,“技術債務”也不例外。

假設性。

一個“技術債務”問題可能永遠都不需要解決。或許程式碼很醜,但如果能正常執行且沒什麼副作用或依賴性,那團隊完全可以專注於其他事,比如為客戶提供價值。認為其需要修復則是誇大了問題本身。如果可以將問題影響區域性化,那這個問題大概就不需要修復。

與擁有貸款人的債務不同,團隊的技術債務沒有限制。

貸款人會評估債務人的還款可能性,併為債務人違約時造成的後果尋求保障。習慣性濫用債務的人最終將再也無法拿到信貸的機會。

相比之下,軟體團隊的限制較少。自動或手動的架構、設計,以及程式碼審查之類都可以防止技術債務意外發生。但在複雜的系統中,審計無法找到的很多錯誤只會在執行的系統中出現。錯誤預算或許能讓團隊在解決缺陷之前不再新增更多功能,但它的前提條件是要能識別出錯誤,而技術債務就像是水下冰山,大部分都是看不見的。

但是在多數情況下,開發團隊可以隨便“釋出”任何包含有意為之的技術債務,而不會有人要他們為自己不可持續的決定負責。事實上,如果他們在面向專案的資金模型組織中工作,那麼他們要做的就是把專案釋出到生產中去,讓 IT 運維去頭疼因此產生的問題,成功讓自己甩鍋。

決策推遲的成本會隨著時間的推移迅速增長。但決策推遲實際不存在。決定在未來採取不同方法不過是額外的工作成本,而如果需要返工的程式碼有大量依賴,重寫程式碼的成本將會疊加式增長(見《尋找管理架構性技術債務的指標》)。技術債務所暗含的複利意味著返工的成本增加,但卻掩蓋了造成成本增加的依賴原因。透過封裝和模組化等設計策略,團隊可以減少甚至完全消除變化所帶來的成本。

只要沒出大事,多陣列織都會無視技術債務。

這就又讓我們回到了第一個問題上,這些問題或許並不需要解決。而即使這些問題真的需要解決,商業利益相關者也大概不會重視。真正的問題在於“技術債務”這個詞將重點僅僅放在了成本上,沒有傳達商業利益相關者會因為忽視技術債務而損失的東西。對於眼裡只看得到一季度或一年的人來說,長遠的可支援行沒什麼討論的必要,也就可擴充套件性和防禦破壞性安全漏洞有些許的說服力。

技術債務很難用財務術語來量化。

就像 Kevlin Henney 在 2022 年 QCon Plus 的演講中所述(可參見 Ben Linders 的 InfoQ 文章《技術債務可量化為金融負債:開發者眼中的不可能》),管理者對團隊無法衡量其技術債務的金融價值感到迷惑,對於耳濡目染“你無法衡量的東西,你也無法管理”

【注 4】

的人來說,無法表達技術債務的財務影響讓團隊看起來很不明智。

架構決策和技術債務

正如我們在前一篇文章中所述,軟體架構是 QAR 驅動的決策,而這些決策可能對技術債務有積極或消極的影響,如圖一所示。決策發生的時間決定了團隊架構設計所要採取的方式。在專案之初,通常也是在確切定義 QAR 之前,便做出多數的架構決定,可能會導致前期架構不易發展,且隨著對 QAR 更準確的定義,也需要大規模重構。與之相反,如果在敏捷架構中的每個階段,逐步做出架構決策,可以更好地適應 QAR 的變化。

幾乎所有的架構決策都是至少兩個 QAR 之間的權衡。如安全性與可用性之間的抉擇,無論怎麼選都有可能增加技術債務,無論是優先考慮可用性但使系統更加脆弱,還是優先安全性但犧牲系統可用性。說到底,隨著使用者數量的增加,或者需要調整 QAR 的優先順序才能讓技術債務更可控,將來的某天我們總要面對這些問題。其他例子還有可擴充套件性和可修改性、可擴充套件性和上市時間。

這些決定通常被描述為“滿足”,也就是“足夠好”。雖然你還可以做得更好,但你選擇在結果足夠好時就停下來。正如《實踐中的持續架構》中所言,“架構決策可以增加或削減技術債務”

【注 5】

。然而,具體增加或削減了多少,這是很難用財務甚至技術術語來量化的。

除非團隊成員非常幸運或者知識極其淵博,否則無論是透過什麼方法,他們所做的部分技術決策可能都需要根據反饋迴路所帶來的資訊(見圖一)在未來進行調整甚至徹底重做。對現有的架構決策進行調整或重做會產生額外工作量,並與其他積壓的任務相競爭,後者常被期望能向利益相關者提供有用功能而被認為擁有更高優先順序。因此,調整或重做架構決策相關的工作可能會被推遲,從而進一步增加系統的“技術債務”。

寫給架構師的技術債“償還”指南

質量屬性、架構決策、技術債務與反饋迴圈

每當團隊做出決策時,都要做好所有這個決策相關工作在未來都可能要返工的準備。因此,團隊需要將決策視作是需要在相當短的時間內驗證或需要的假設,以確保所作的工作在未來的某一時刻不會被刪除。

因為所有工作至少在驗證之前,都有可能產生額外的返工工作量,所以,團隊可以嘗試以下幾點:

推遲決策到萬不得已時再決定;

儘快驗證必須做出的決策,以限制潛在的成本風險;

透過封裝和抽象等設計技巧減少依賴關係的增長。

瞭解並接收決策對技術債務的影響有助於團隊更好地做出決策。但由於其很難透過財務術語量化,技術債務對評估決策成本沒有幫助,且很難被用作是評估至少兩個 QAR 之間權衡的精確評估工具。

讓我們再回到安全性與可用性的例子。要想在短時間內部署一個 MVP,我們很難估算最小可用架構(MVA)在優先可用性而非安全性時所帶來的財務影響。更好的方案是做出一系列最小化決策後,隨著時間的推移,藉助經驗對其進行測試和發展。這些決策應當搭配一套最小架構實踐加以補充,以幫助團隊在發展產品的同時保持架構的可行性。

當然,架構工作中最重要的一部分就是溝通,即使我們無法將與決策相關的技術債務數量進行準確量化,還是可以利用這一比喻可以幫助團隊溝通決策的長期影響。

延遲維護:或許是更合適的用詞?

技術債務在工程界有另一個說法:延遲維護。延遲維護是設計優秀的大橋斷裂、設計優秀的大樓坍塌、設計優秀的飛機從空中墜落的原因。在物理學中,熵的增加是有代價的,而如果無法領先熵的增長將會產生災難性後果。

分析物理學延遲維護成本的優勢在於,我們能更清晰地看到維護被推遲時,成本是如何快速累加的:如果底層鋼板沒什麼問題,那麼密封圖層就足夠了。而一旦鋼板開始鏽蝕,在重新噴漆之前就必須先清理乾淨舊塗層和鐵鏽。如果鋼板已經出現裂痕,那麼就還需要加固,裂痕過於嚴重甚至還可能需要更換全部的結構。

對於軟體來說,事情遠沒這麼簡單。錯誤不易被檢查發現,再加上元件之間互動導致返工可能影響到全部程式碼庫。即使是“簡單”的元件替換也會非常困難,因為新元件可能有副作用,或者需要不同的引數資料,而呼叫它的程式碼可能無法訪問這些資料。如果變動的是如調整演算法等更深層次程式碼,那麼成本將會是指數級地增加。

但就如“維護”一詞也是有限制的。“維護”通常是指對磨損部件的簡單維護,但軟體不會隨著使用而磨損。軟體的變化可能由外部事件引起,如作業系統或框架的變化、供應商倒閉,或者基礎設施軟體的新版本,以及更具破壞性的,由客戶行為、商業運作或組織戰略變化等造成的影響。

每一種用詞都有其侷限性,有時我們必須拋棄這些術語,才能找到更好的模型來幫助我們做出決策。

結   論

多數團隊並不認為目前的決策在未來可能會被撤銷或返工,但現實中事情總會發生變化,而我們需要不同的方式以面對這些變化。雖然團隊無法預測未來,但他們可以透過實驗,在變更所帶來的影響變得無法接收之前檢測出這種可能性。

技術債務是對未來變更工作量已知的一個例子,常發生於團隊決定推遲必須要完成的工作量。債務一詞意味著,處理這類變化所需的成本將會隨著時間的推移呈指數上升,與複利類似。但矛盾的是,正如我們在本文中所述,技術債務很難用財務術語進行量化,這也限制了它在決策評估成本模型中的作用。

雖然技術債務有助於向利益相關者傳達團隊決策的技術影響,但更合適的方法是透過質量屬性要求重塑討論,讓利益相關者將其看作是軟體系統必備的能力,而非是需要完成的工作量。

最後,感謝 Thomas Betts、Murat Erder、John Klein、Philippe Kruchten 以及 Eoin Woods 為本文的初版審閱。

尾註:

Ward Cunningham,《WyCash 投資組合管理系統》,ACM SIGPLAN OOPS Messenger4, no。2 (1992)

Philippe Kruchten, Rod Nord, and Ipek Ozkaya, 《管理技術債務:減少軟體開發中的摩擦》(Addison-Wesley, 2019)。

Murat Erder, Pierre Pureur, and Eoin Woods, 《實踐中的持續架構》 (Addison-Wesley, 2021)

這句話經常被認為是 Peter Drucker 和 W。Edwards Deming 說的。

Murat Erder, Pierre Pureur, and Eoin Woods, 《實踐中的持續架構》 (Addison-Wesley, 2021)

原文連結

https://www。infoq。com/articles/technical-debt-tells-you/

中臺是企業架構的又一次實踐嗎?(

https://xie。infoq。cn/article/dfc3d5f90b35097f302e04603

企業級業務架構設計:方法論與實踐學習筆記二 (

https://xie。infoq。cn/article/adaeb3092ea6ae303f5fac1b4

阿里是如何使用分散式架構的?阿里內部學習手冊分享 (

https://xie。infoq。cn/article/a686033bb921267fdf8e0c71a

Github 限時開源!Alibaba 最新版億級高併發系統架構 (

https://xie。infoq。cn/article/460610c8ceb31423663c26213

宣告:本文為 InfoQ 翻譯,未經許可禁止轉載。

炒股開戶享福利,入金抽188元紅包,100%中獎!

開啟App看更多精彩內容