Teddy 再談技術債一文有提到,軟體品質有分「外在品質」與「內在品質」。外在品質是使用者直接感受到的品質,而內在品質則是開發者才有辦法感受到的真相。
「魚與熊掌,不可兼得」,這兩種品質也是一樣,開發者在同一時間裡,提升其中一種品質,另一種品質很有可能會被犧牲。比方說:想提升外在品質需要「增加新功能開發」,但會犧牲內在品質「欠技術債」;如果提升內在品質要「重構還債」,但會犧牲外在品質「減少新功能開發」。
古人有云:「時勢造英雄」,英雄之所以是英雄,正是在對的時間,做對的事。公司的決策者,在決定如何提升這兩種品質的策略前,必須謹慎思考。常會聽到有人說:先求有,再求好,「先求有」指的是「提升外在品質並犧牲內在品質」,這通常是業務人員所想要的;「再求好」則是「提升內在品質並犧牲外在品質」,這是開發人員所想要的。「先求有,再求好」的過程打比方就像是:新創產品先求推出市場,等驗證使用者需求後,再開始改善程式內部設計。
這時有個很大的盲點:什麼時候該開始「求好」?大家可能會想到:「當產品穩定呀!」。可是瑞凡,真的要等產品穩定的話,內在品質就回不去了。因為對業務人員來說,產品的外在品質永遠都有改善空間啊!因此產品穩定並不是一個明確的指標。
或許可以換個角度:欠技術債有可怕的時間利息,但可以加速提升外在品質,在死亡交叉前,確實是能感受到加速的。但如果持續不還債,直到過了死亡交叉後,舊技術債的時間利息開始超過加速的時間,這時再欠技術債已經沒意義了,因為無法達到想要的效果。如果能在死亡交叉前,投入部分時間資源來還債的話,下次需要加速提升外在品質就比較不擔心倒債。
但是,令決策者困擾的是,內在品質不僅難以量化,而且只有第一線的開發者才會了解,身為非技術人員的決策者很難體會,可是這會影響後續的決策,不去了解會下錯決定,對公司的營運是不利的。
還好,在死亡交叉前通常會有警訊,注意下面這些狀況,並多關心開發者與他們才知道的真相。沒事的話當然很好,但如果已債台高築的話,得開始計畫「求好」,重構償還債務。「有借有還,再借不難」,下一次有緊急程式修改需求(如修復線上嚴重 bug),才不會被技術債勒索時間,錯過黃金救援時刻。
新功能開發團隊估算功能實作要五天時間,雖然實際時間不是很準確,但誤差也只是一兩天。但過了兩三個月,團隊實作時間越來越不準,誤差越來越大,團隊估時也不斷增長。即使非技術人員佛心說無法預期的時間可以盡量加,但實作的時間還是遠遠大於估算時間。
這時就得關心一下是否有技術債阻礙團隊開發。
當團隊第一天來的新人,與三個月後來的新人,在進入產品開發所需要的時間明顯變長。在這三個月中,產品本身商業邏輯的難度提升需要考慮進去,如果明顯沒有太困難,但時間變得不合理的長,有可能是這三個月中累積了太多技術債。
另一種情境是,如果老鳥要持續開發新功能,但新人剛進公司給三個月只看程式碼不開發,代表這份程式碼可能有很大的技術債,比方說:只有老鳥會清楚地雷在哪,新人則需要花三個月時間了解地雷,並還要想辦法跟地雷好好相處。
技術債多代表程式碼難改;難改的程式自然會很多 bug ; bug 多,可能沒發現的 bug 也很多;沒發現的 bug 又有機會成為新的技術債。如此循環, bug 率就會不斷上升。
因 bug 率高,可能後續就會開始安排測試人員協助測試。
這是增加了一個關卡,同時也代表開發時間拉長;也因為沒發現的 bug 變多,且有可能是測試人員發現,修復難度就會大幅提升,自然就需要花更多的時間修 bug 了。
因對自己不熟的業務掌握度不高,因此可能會寫出更多 bug 。於是乎,團隊會產生一種默契:職責完全切分,只改自己熟的部分。當在詢問自己不熟業務上的技術問題時,也同時會把責任推給熟悉領域的同事,比方說:「這可能要問某某某耶,因為這是他設計的。」
如果需求需要更動的程式範圍,橫跨整個團隊,而團隊要實現需求還必須每個成員找來交待需求內容,成員之間還得討論資料交換的方法,太複雜了!這明顯也是「技術上會難以修改的理由」,因此,知識在團隊內不流通也是一種技術債。