Deal with technical debt

27 February 2024

本篇文章為閱讀medium文章的心得: How To Deal With Technical Debt

文章主要的outline如下

  1. 定義何為Technical Debt以及種類
  2. 處理Technical Debt的動機以及好處
  3. 處理Techincal Debt的策略
  4. 如何避免產生Techincal Debt

這篇文章我自己認為對於Software Engineer以及Manager都或多或少有用,對於software engineer能夠更清楚知道自己為何要處理techincal debt, 以及能夠更清楚跟上面解釋這件事”It matters”。此外,也能更有方向、效率地去做這件事,能夠先找出technical debt有哪些,並且能夠去分類他們的priority並且有效的安排資源去做。因為確實有可能花很多資源去處理的technical debt並沒有什麼實質效應。

對於Manager則是能讓上層知道為何需要安排資源去處理Technical Debt這件事, 儘管可能乍聽之下他不是一個有產出或者impact的事情(例如refactor或許能增加可讀性, 但resource應該要用在其他比refactor更重要的任務, 所以不太願意花資源去處理technical debt), 但我們能透過以下說明Technical Debt會導致RD開發效率低落,以及寫出quality不好的code。

Technical Debt定義

簡單而言,Techincal Debt的定義為會讓工程師在開發上速度變慢的因素、問題都可以稱作是Techincal Debt. 可能是library過於老舊,導致新的tool, API不能使用,可能是長期疊床架屋的結果導致現在要新增功能、修改code變得相當不容易,很容易寫出bug。

以公務員的SOP舉例。SOP可能是幾十年前的人定下來的,但長期下來可能發生幾個問題

  1. 可能科技發達,有了電腦(新技術,新tool, library, 演算法)。這些SOP可能過時了 變得相當沒效率
  2. 可能後來業務有些新增或者改變導致後續的SOP不斷疊床架屋導致SOP變得相當複雜,之後不容易修改, 或者修改可能有bug
  3. 可能當時訂立時沒發現,但這些SOP可能有些問題

此時要修改SOP就會變成是一件困難的事,以問題1而言,可能會有很多公務員處理問題依賴就有的方式,要採用新的技術對他們來說並不容易,以問題2,3則會變成SOP過於複雜,但很多細項定義我們並不知道是那時候的人定義錯,還是他真的有某些原因做出這樣的定義,在這種情況下會讓修改SOP變得窒礙難行。

同理套用在軟體開發上,就會是一下狀況:

  1. 因為依賴過時的tool, library版本,導致原本寫法在舊版會work, 一旦compiler版本更新,或者採用新的C++ standard, 程式就會編譯不過
  2. 舊有的code疊床架屋解決各種問題,可能在debug或者enhance時變得相當困難,可能會漏考慮,漏修改一些地方,又或者使code複雜度因為patch上去變得又更加複雜, 舊有的code可能有些也沒辦法判斷是當初預期就這樣的結果還是他是bug

這些問題都會導致開發者開發速率下降。

Technical Debt種類

以下1-8是文章中的舉例,當然還有更多,例如debug速度過慢,沒有好的log system等等

  1. Code Quality: code不是self-explained, 有很多的comment, 沒有coding standards, 沒有好的design
  2. testing: 沒有好的unittest, regression框架
  3. Coupling: 許多code相互依賴,導致牽一髮動全身,改一個功能結果另一個功能壞掉
  4. Out of date library, tools: 新的API不能用,只能使用舊的coding style
  5. Manual effort: 例如沒有CI/CD導致很多重複流程都要RD做
  6. Lack of Documentation
  7. System Design: 沒有好的design導致程式碼的scalability很低
  8. 沒有好的sharing, wramp up process:導致新人很難上手,很多東西也要花時間去學習或教導

但我們常以忙碌為藉口認為這件事情做了效益不大,不如focus在實質問題上,導致這些技術債一直沒得到處理累積,但其實可以評估,解決他們搞不好可以提昇RD開發速度。

處理技術債的策略

首先要先思考為何要處理技術債
處理技術債的誘因在於: 這些問題減慢了RD開發速度。 如果這件事情本身不會造成開發速度減慢,或者長久以來修改的次數微乎其微,那這個技術債似乎就沒有處理的必要。

分析開發模式跟codebase
這個步驟目的在於找到目前開發變慢的bottle necks, 是哪些技術債導致的bottle neck。 技術債可能很多,但不見得每個都會影響開發速度。

排列技術債的優先程度
這個步驟在於讓我們prioterize技術債的項目,作法很多,文章中的做法是偏向分析每個項目的effort/value來判斷這個技術債的嚴重性

value的話可以用這兩個指標來做量化

  1. 如果不做任何事, 事情會在現在或者之後變得更糟嗎?
  2. 這部分的程式碼最近是否有擴充,修改的tasks

以上步驟列出的算是此技術債的value, 接著可以配合需要的effort來決定事情的優先度

其他分析的指標包括: RICE, Effort and Pain

如何避免建造技術債

技術債造成原因往往是因為時程問題,急著需要某個功能,因此沒時間好好規劃,做好文件,弄好測資,導致數年後沒人知道這段程式碼是在幹嘛的,或者沒考慮清楚導致之後擴充相當難進行。

具體作法如下:

  1. Documentation
  2. write test
  3. TDD(test driven design): 先有測資在寫code, 利用測資先確立好SPEC
  4. 建立好的coding standard (參數命名, 上code時,commit, CL的description應該要詳細說明每段修改的目的為何,注重在修改的目的而不是修改的原因)