[料理秘方] 隱身在程式碼堆中的背後靈 - 技術債

技術債是一種「任何有意或無意地做出可能不利於日後修改或擴展系統的錯誤或非最佳的設計決策所帶來了的設計導正工作」,我們說簡單一點,在軟體開發的過程當中,我們或許出於無奈、又或者始於無能,採用了會對將來修改或擴展系統造成麻煩的設計方式,而「改採用正確的設計方式的修改工作」就是等待償還的技術債。

Ward Cunningham 在 1992 年的一份報告中用了一個很好的比喻,技術債類似於一般的財務負債,我們貸款或刷卡買東西就會欠下債務,如果我們定期有償還貸款的本金或是繳清帳單,問題就不大,但是如果我們選擇只還息或是只支付最低應繳金額,甚至賴帳,就會固定產生一筆款項來支付利息,隨著我們軟體愈加發展,借的技術債愈多,需要支付的利息也就愈多,可怕的是技術債是複利的,如果利息多到我們還不起,那些付不起的利息就會滾入本金,如此循環,直到我們沒錢了,只好放棄該軟體,宣佈破產。

有人說「有意的」才是技術債,而「無意的」不是,個人傾向是不管它是有意或無意,因為當我打開一份 Legacy Code 時,我無法猜測當初設計的人是有意還是無意,但是「改採用正確的設計方式的修改工作」還是得做。

技術債的種類

技術債的種類大致上可以有這幾種類型:

  • 程式碼債務:靜態程式碼分析工具的違規及 Code Style 不一致
  • 設計債務:壞味道及違反設計原則
  • 測試債務:測試不足、測試涵蓋率不夠以及不合理的測試設計。
  • 文件債務:缺乏重要商業邏輯的文件、難以閱讀的文件以及文件失真。

技術債的影響

技術債會造成修改或擴展系統的困難,使得花費的 CoC(Cost of Change)因技術債的多寡而增減(CoC 與技術債呈現正相關),除此之外技術債還會打擊開發團隊的士氣,若技術債不斷地累積,程式將變得難以修改,導致開發團隊開始氣餒、鬱悶,而當償還全部的技術債不再是兩三天就能完成的任務時,開發團隊的士氣會受到更深一層的打擊。

為什麼會有技術債?

大致上就分成兩種:無奈及無能。

  • 時程壓力:在面臨專案 Deadline 的壓力時,為了儘快上線、結案,程式設計師大都會妥協,採取比較草率的設計方式,先過眼前這一關再說。
  • 缺少優秀的程式設計師人月神話裡面說「研究顯示,高手與庸手的表現有著極大的差異,而且往往是一個數量級的表異。」,程式設計師對設計及相關原則缺乏基礎的話,那麼就不必期待設計出來的成果能夠擁有高品質的水準,而這類的程式設計師往往也難以勝任主要的設計工作,否則最終會將開發團隊引入歧途。
  • 未遵循設計原則:如果開發人員不懂設計原則或沒有實踐過設計原則的經驗,寫出來的程式碼往往難以修改及擴展。
  • 不懂壞味道及重構:壞味道可以顯示出設計在結構上的品質有問題,會帶來技術債,即時地重構,可以消除這種壞味道,可是,如果開發人員不懂也不進行重構,那麼技術債就會隨著時間越積越多。

技術債到底要不要還?

欠債要欠得高明,最好是「有意」地欠債,為了搶市而有意留下的技術債,在產品確認有其市場時,應該儘快安排資源還債,以確保後續的產品開發不會因為技術債而受到拖延,在償還技術債的選擇也應該從利息最高、影響開發最深的開始處理,對於那些超低利率貸款或是無息貸款,如果負擔這些利息並不影響產品的開發,這類的技術債可以延後償還,甚至不償還都沒有關係。

人月神話裡面有說到「現代軟體系統中都少不了的天生特質:複雜性、配合性、易變性、隱匿性。」,這種天生特質導致軟體設計本質上的困難,為了解決這個難題,我們必遵循良好的設計方式,而技術債就是因為做了不良的設計決策所帶來的其中一種結果,因此消弭技術債將有助於我們解決軟體設計的困難。

參考資料

相關資源

C# 指南
ASP.NET 教學
ASP.NET MVC 指引
Azure SQL Database 教學
SQL Server 教學
Xamarin.Forms 教學