技術債正在悄悄拖垮你的團隊!

JavaEdge發表於2024-11-24

0 前言

軟體開發的核心在於應對變化。在軟體的生命週期中,目標是能夠在合理的時間內實施必要的更改。不管這些更改是技術性的,比如緊急安全升級,還是業務需求所驅動的,比如開發新功能以在目標市場中更具競爭力——能否快速應對變化是成敗的關鍵。

是什麼讓我們慢下來?通常,這是因為讓某個功能能夠執行並不等於讓它在長期內具備良好的可維護性(參考 Google 軟體工程實踐)。第一個可執行版本通常是快速而粗糙的,而讓其具備可修改性則需要額外的努力。這引出了“技術債務”的隱喻(參考 Ward 的解釋)。開發人員選擇暫時不投資於程式碼的可變更性,而是承受技術債務,以便更快完成任務。之後,每次修改程式碼都需要支付額外的“利息”,直到技術債務徹底清償。

1 啥是技術債?

技術債務是指當前軟體狀態與最適合於輕鬆實現更改的目標狀態之間的差距。在某些情況下,積累技術債務可能是值得的——例如,為了滿足一個硬性截止日期,否則整個專案可能停滯不前。但從長遠來看,採取措施來控制和減少技術債務無疑是明智的(參考 Fowler 的文章)。

對於壽命預計以年為單位的軟體來說,是否償還技術債務並不是問題。問題在於如何識別、衡量和管理它。

技術債務可能有不同的來源。例如,團隊可能對技術債務引發的問題缺乏認識;或者,儘管意識到問題存在,但誤以為永遠沒有時間解決。這與工程文化密切相關。隨著時間推移,問題只會越來越嚴重(參考 破窗理論)。另一種情況是,團隊在權衡利弊後,有意積累技術債務。第三種情況則是因為我們無法事先掌握所有資訊,需求可能變化,而開發過程中會逐步學習。這種債務即使對於最優秀的團隊來說也不可避免(參考 Fowler 的技術債務象限)。

技術債務的棘手之處在於,它透過不斷做出小的妥協而逐漸積累。為了短期的便利和簡單而犧牲長期的結果,被稱為“溫水煮青蛙隱喻”。換句話說,問題會逐漸積累,直到災難發生為止。我們如何防止這種情況的發生?

應對技術債務的最佳防禦措施是從一開始就使其可見。然後,我們可以透過設立適當的健康指標,並儘早採取糾正措施來主動管理它。

另一方面,如果我們的系統已經因為技術債務瀕臨崩潰,那就需要採取更激進的“清理”措施——在為時已晚之前。在這種情況下,建議建立多個改進指標,並使用它們來跟蹤這些措施的進展。

2 WTFs 每分鐘

一個廣泛認可的觀點是,程式碼質量的唯一有效衡量指標是每分鐘 WTF 次數(參考 Martin 的《程式碼整潔之道》)。或許可以開發一款裝置,專門用來統計 WTF 次數,這或許會成為一個不錯的創業點子?

當然,這個指標既主觀又依賴於開發者的技術水平及團隊的工程文化。根據破窗理論,糟糕的程式碼越多,就越會鼓勵開發人員繼續製造技術債務。

3 程式碼異味的數量

Martin Fowler 和 Kent Beck 引入了“程式碼異味”這一概念,幫助開發者識別程式碼中可能存在問題的地方。Fowler 的《重構》一書列舉了 24 個程式碼異味示例。Uncle Bob 的《程式碼整潔之道》中也包含了許多程式碼異味和啟發式規則(參考《[程式碼整潔之道》第17章](https://learning.oreilly.com/library/view/clean-code-a/9780136083238/chapter17.xhtml#:-:text=Smells and Heuristics))。一些程式碼異味,如重複程式碼和過長函式,可以透過靜態分析工具(如 [SonarQube](https://docs.sonarqube.org/9.6/user-guide/concepts/#:~:text=Code smell,errors as they make changes.))輕鬆檢測。然而,許多程式碼異味無法透過靜態工具輕鬆發現。這也是為什麼需要像“每分鐘 WTF 次數”這樣的另一個指標。

4 自動化測試覆蓋率

儘管早在[《Google 軟體工程實踐》](https://abseil.io/resources/swe-book/html/ch11.html#:~:text=We have a name for,changes across the entire codebase.)、《程式碼整潔之道》](https://learning.oreilly.com/library/view/clean-coder-the/9780132542913/ch01.xhtml#:-:text=Am I suggesting,be tested. Period.) 等書中提到過自動化測試的重要性,最近的研究(例如《Accelerate》和 DORA 研究)表明,測試自動化與軟體生產力之間存在統計上的正相關。這表明,提高自動化測試覆蓋率通常可以顯著提升團隊的生產力。

可以透過許多工具(例如 [JaCoCo](https://www.eclemma.org/jacoco/#:~:text=JaCoCo is a free code,existing libraries for many years.))來追蹤這個指標。但如同許多其他指標一樣,它也容易被“造假”,比如編寫大量實際上並未測試任何內容的測試。因此,結合其他努力來提升團隊技能,並闡明編寫自測試程式碼的好處是非常重要的——比如 Google 推行的廁所上的測試

當測試自動化覆蓋率較低成為限制團隊進步的因素時,這一指標尤為有效。例如,我的團隊曾發現某個遺留元件的測試自動化覆蓋率非常低(僅約50%)。因此,我們將提高該覆蓋率作為優先事項。透過持續監控指標、在團隊回顧會議上討論進展,我們在一年內將單元測試覆蓋率提升至80%,並且不再視其為限制因素。現在,我們將其作為程式碼庫健康的一個重要指標。

5 文件覆蓋率

文件不足可能對團隊效率產生負面影響。因此,我們可以採用一個與文件覆蓋率相關的指標:

文件覆蓋率:系統中文件覆蓋部分佔總系統的百分比。

如何使用這個指標?在文件不足被視為制約因素的團隊中,可以優先改善這一問題。我們列出所有元件,並評估每個元件當前的文件覆蓋情況。每週更新指標,並監控改進進展。

6 用在棄用元件上的精力

在一些情況下,為了支援新的元件,我們需要棄用舊元件,但在一段時間內仍然不得不保留這些元件。例如,有些客戶端需要時間完成遷移。在此期間,我們仍可能需要對這些棄用元件進行工作,比如修復漏洞。由於這些棄用元件最終會被移除,這種工作實際上是一種浪費。問題是,團隊往往會“忘記”這些棄用元件,繼續對它們提供支援。隨著時間推移,這些工作會不斷積累,甚至可能成為團隊的主要限制因素之一。因此,跟蹤棄用元件並儘早廢止它們是非常重要的。

可以採用以下指標:

  • 棄用元件工作的比例 = 用在棄用元件上的時間 / 總時間
  • 棄用元件工作的比例 = 與棄用元件相關的任務數 / 總任務數
  • 棄用變更比例 = 棄用元件的變更數 / 總變更數

如何使用這些指標?例如,我的團隊負責一個覆蓋 200 多個國家的住宿合作伙伴門戶中與發票相關的財務內容。去年,我們開發了一個新的發票展示頁面,並在幾乎所有國家推出。然而,由於一些國家有特定邏輯,我們決定暫時保留舊頁面以便後續遷移。這一決定讓我們可以更快地獲得新頁面的反饋。然而,這也導致我們在幾個月內需要支援多個版本的頁面。儘管舊頁面的支援工作量不大,但累積效應可能會顯著增加負擔。在這種情況下,我們將這一指標作為改進和健康監控的重要工具。

7 用於修復使用者發現缺陷的工作量

軟體中的缺陷顯然會減緩功能開發的進度。因此,這些缺陷可以被視為技術債務的一部分。

我們可以使用以下指標來量化相關工作量:

  • %修復缺陷的工作量 = 修復缺陷所花的時間 / 總時間
  • %修復缺陷的工作量 = 缺陷數量 / 總任務數量

8 漏洞的數量

OWASP Top Ten 網路應用安全風險列表中,“漏洞和過時元件”被列為其中之一。這些問題可能導致緊急計劃外工作,來修復漏洞和應對後果。因此,漏洞可以被視為技術債務的一部分。

我們可以使用工具 Dependency-Check 來檢查專案中的依賴項。將該工具整合到 CI/CD 流水線中是廣泛認可的最佳實踐。這種方法可以幫助我們儘早發現並修復漏洞或過時元件,從而減少技術債務帶來的潛在影響。

9 清償技術債務所需的估計工作量

有些導致團隊效率降低的問題無法透過靜態分析工具輕鬆追蹤。例如,共享資料庫架構或其他複雜的架構問題,通常難以用工具直接衡量。每個團隊都會面臨其獨特的技術債務挑戰,因此解決方法也會有所不同。

最簡單的衡量方式可能是估算清償技術債務所需的工作量。然而,這種估算需要團隊具備足夠的技能和經驗,例如掌握設計模式、重構技巧、自測試程式碼的編寫,甚至是架構最佳實踐(如松耦合架構)等。透過結合這些能力,我們可以更準確地評估並應對技術債務。

10 關鍵總結

  • 技術債務是指當前軟體狀態與最適合輕鬆實現更改的目標狀態之間的差距。
  • 在幾乎所有情況下,保持技術債務處於較低水平是非常重要的。如果忽視它,每次修改程式碼時都會付出額外的努力。
  • 技術債務的來源包括:(i) 團隊對其危害缺乏認識;(ii) 在權衡利弊後有意選擇積累技術債務;(iii) 由於資訊不完整,隨著開發過程中的學習和需求變化不可避免地產生的債務。
  • 技術債務往往透過無數次小的妥協逐漸積累,最終可能導致嚴重後果。
  • 最好的實踐是從一開始就讓技術債務變得可見,並透過設定健康指標進行監控,在早期採取糾正措施。
  • 如果發現技術債務已經威脅到系統的正常執行,則需要採取更加激進的清理措施。在這種情況下,可以透過設立改進指標並定期跟蹤進展來評估和調整清理策略。
  • 各團隊可以使用多種指標來衡量技術債務的健康狀況和改進效果,例如 WTFs 每分鐘、程式碼異味數量、漏洞數量、測試覆蓋率、文件覆蓋率,以及用於棄用元件、計劃外工作、修復缺陷的工作量和清償技術債務的估算工作量。這些指標並非唯一選擇,團隊可以根據自身需求設計更合適的指標。

關注我,緊跟本系列專欄文章,咱們下篇再續!

作者簡介:魔都架構師,多家大廠後端一線研發經驗,在分散式系統設計、資料平臺架構和AI應用開發等領域都有豐富實踐經驗。

各大技術社群頭部專家博主。具有豐富的引領團隊經驗,深厚業務架構和解決方案的積累。

負責:

  • 中央/分銷預訂系統效能最佳化
  • 活動&券等營銷中臺建設
  • 交易平臺及資料中臺等架構和開發設計
  • 車聯網核心平臺-物聯網連線平臺、大資料平臺架構設計及最佳化
  • LLM Agent應用開發
  • 區塊鏈應用開發
  • 大資料開發挖掘經驗
  • 推薦系統專案

目前主攻市級軟體專案設計、構建服務全社會的應用系統。

參考:

  • 程式設計嚴選網

本文由部落格一文多發平臺 OpenWrite 釋出!

相關文章