在數字化時代,每一個組織的經營都是建立在數字化的系統之上的,而數字化系統的構建,必然就會帶來技術債務,這是每一個數字化團隊都要面臨的一個問題,如何有效的管控技術債務。
技術債務的產生,是技術團隊不斷迭代構建系統過程中,無法一次性預設所有的需求,而隨之產生了系統設計上的扭曲失真。
在瞭解了技術債務產生的原因後,就可以將技術債務和團隊的作為或不作為聯絡起來,使用一些有效的策略和方法,來最大限度的減少技術債務的積累,保持系統的持續健康。
垃圾回收模型
有效控制技術債務最小化的方法,可以從現代性的軟體設計模式中去借鑑思路:垃圾回收演算法。
相信熟悉JAVA和Golang等現代開發語言的人,對記憶體垃圾回收的概念,是非常熟悉的。其實,一個專案的技術債務的產生和積累,也就如同一個程式的記憶體分配和管理是一樣的。
對記憶體垃圾收集的描述為:
執行程式會建立垃圾(garbage),即已分配但未使用的記憶體。垃圾的產生是不可避免的,因此我們必須偶爾停下來收集垃圾。如果停頓是可預測的,而且很短,那就更好了。有各種各樣的垃圾收集演算法,它們具有不同的屬性。
對團隊技術債務的描述,也可以如此:
執行有時間限制的迭代會產生技術債務,即使用過時的設計編寫程式碼。創造技術債務是不可避免的,所以我們必須偶爾停下來重構程式碼。如果這些停頓是可預測的、短的,那就更好了。存在各種具有不同屬性的迭代軟體開發過程。
一個團隊的軟體開發過程是一個由團隊自己執行的演算法,它產生並清理了一種我們稱之為技術債務的垃圾。
那依次延伸,軟體開發過程,就可以使用兩種方法來控制技術債務:
- 第一種方法是清理現有的技術債務。大多數團隊已經透過重構來做到這一點。
- 第二是避免技術債務的產生。這種情況不太常見,但更有趣。
清理法
團隊可以在技術債務存在後,透過清理的方式來處理債務。
通常情況下,一個團隊在不考慮現有設計的情況下“倉促”完成一個功能,確定技術債務,然後才進行重構以清除債務。有時清理工作會立即進行,但也可能要很晚才得以開展。
小問題可以在幾分鐘內重構,但大問題可能就需要幾天、幾周,甚至幾個月的投入。當開發人員在編寫功能時停下來解決技術債務時,這就像垃圾收集器停下來清理垃圾一樣,把時間花在重構上意味著花在新特性上的時間更少,同時當問題越大時,重構所需的時間也就越長。
因為清理債務需要從新功能的構建中去擠佔時間,團隊會發現自己面臨著減少重構的壓力,特別是大型系統重構。導致的後果就是,他們只清理了小問題,卻延遲了大問題的清理,比如系統的架構。推遲一個小的清理會把它變成一個大的清理,因為隨著時間的推移,程式碼會圍繞這個問題構建起來,它也必須被重構。
預防法
團隊也可以透過減少技術債務的產生來控制技術債務,也就是說,儘可能的預防技術債務。
譬如,團隊透過考慮設計方案,並選擇產生最少技術債務的方案來做到這一點。當被要求新增一個新功能時,團隊會考慮當前的設計能在多大程度上適應該功能。如果設計已經是合適的,他們就新增功能。但如果設計不合適,他們會先更新設計,然後再新增功能。
對許多開發人員來說,避免問題聽起來要比解決問題更好。然而,遺憾的是,一些技術債務是不可避免的,遲早,新的功能需求會成為令人不快的驚喜。
同時,團隊也會擔心,技術債務規避是一個變相的瀑布式流程,或者更糟,是一個預先設計好的大專案。其實不然,因為瀑布式流程會讓團隊檢視所有的需求,並交付一個系統來完成所有需求。技術債務避免意味著團隊迭代地處理需求,在每次迭代中交付一個工作系統。
另外,團隊也會擔心,技術債務規避會導致分析癱瘓。大部分的時候,團隊依然會在每一次的迭代中持續交付新功能。
可選4類清理策略
在基本的2個策略的基礎上,我們可以進一步延伸,擴充套件出一個四象限的策略組合:放任自流,被動清理,主動預防,雙管齊下。具體如下圖所示:
技術債務是一個不可完全馴服的怪物。,我們無法徹底的根除,只能選擇合適的策略與之共存。
所以,所有最好的演算法,任何團隊,都要根據自身具體的情況,譬如團隊的結構,系統的規模、業務領域的複雜度、團隊能力和經驗,以及進度的壓力等,綜合來選擇適合的策略。
放任自流
在一些場景下,團隊可以對技術債務採取放任自流的策略。
譬如,你為自己編寫了一個快速處理資料的指令碼,並且也不打算重用它,為什麼要擔心技術債呢?
同樣,這個策略也可以適用於大一點專案,譬如,大型的電腦遊戲,開發者知道他們將為下一款遊戲開始新的系統,所以在遊戲發行之前,只需忍受技術債務的困擾就可以了。
類似的一次性的系統,放任自流,也是一種可選的策略。
被動清理
被動清理,就是團隊只使用技術債務的清理策略。
這是現在大多數團隊所採取的策略。團隊的重點始終在構建新功能之上,只是抽空來清理一些細小的技術債務。
因此,更大的清理工作就變的有挑戰了,所以早期的錯誤會一直存在,導致的就是以後重構的代價會更大,這是一個潛在的隱患。
當然,識別問題比規避問題要容易的多,所以在開發人員的設計能力有限時,被動的清理依然是有意義的。
主動預防
這種只使用技術債務提前規避的主動策略,在今天大部分團隊內是並不常見的。
其實,如果你能透過一些事先的思考,來避免技術債務的產生,這要比陷入明顯的問題要有效得多。
另一方面,如果你對正在使用的技術沒有充足的經驗,你可能會因為錯誤的假設而浪費了時間。儘管努力避免技術債務,但它還是會發生,所以使用主動預防策略的團隊,可能會切換到雙管齊下的策略之上去。
雙管齊下
當團隊希望自身技術債務更低更可控的時候,大部分時候都是採取雙管齊下的策略,將清理和預防都使用起來。
譬如,在每次迭代的開始,團隊討論新的功能需求將如何影響當前的設計,這樣可以保持迭代設計的重點,並讓每個人都對設計有理解和掌握度。
團隊可能對系統未來的新功能有一定的前瞻的預期假設,即使他們現在沒有在做這些需求,但是因為知道未來會發生什麼,可能有助於他們更好的思考今天的設計和決策。
有的時候,一個新功能很難新增到現在的設計中,因為它可能與當前領域的假設是相矛盾,或者很難在當前架構中來構建的。
如果開發人員可以重做設計,並在當前迭代中新增功能,那就太好了,如果不能,他們還可以和產品負責人溝通。在做出決定之前,他們會權衡干係人訴求,進度壓力和工程風險等。
最終的答案,可能是先推出該功能,然後再清理技術債務,或者完全推遲交付該功能,或者介於兩者之間等。
有限和無限遊戲
其實,決定那中策略適合當前團隊的關鍵因素,是在於團隊是在玩什麼模式的遊戲:有限遊戲 or 無限遊戲。
有限遊戲有輸也有贏,無限遊戲可能會失敗,但勝利只意味著你可以繼續玩下去。技術債務有點像一場無限遊戲:如果你能控制它,你就能繼續玩下去。否則,你輸了,並宣佈技術債務破產。
有嚴格Deadline的團隊是在玩有限的遊戲。團隊需要按時的完成任務,那就會積累了大量的技術債務。
初創企業也是一系列有限遊戲。為了達到下一個里程碑,團隊採取了孤注一擲的模式,因為失敗意味著公司的終結。
團隊缺乏經驗,也會迫使你玩一個有限的遊戲。如果開發人員不瞭解問題領域或實現技術,他們就會陷入有限的遊戲中,直到他們能夠構建一些可行的東西。
當然,從有限遊戲,轉換到無限遊戲時,也會導致技術債務的破產。如果你接受破產,並重啟新的遊戲時,就需要重新評估你的策略的選擇了。
不能試圖一直使用一種針對有限遊戲的策略,來希望玩轉一個無限遊戲。
無限遊戲更適合雙管齊下的平衡策略,既可以透過良好的設計實踐避免技術債務,又可以透過重構清理不可避免的債務。
寫在最後
避免技術債務破產的核心:就是最小化技術債務。
在迭代構建軟體時,就無法避免到技術債務的產生,因為我們永遠也無法預期所有的功能需求,系統是在生長演進之中,那我們的設計和程式碼,就會存在設計上侷限性和扭曲。
管理技術債務就如同程式記憶體分配和管理一樣,透過最佳化和改進團隊的開發過程,來控制技術債務的產生和積累,將團隊的技術債務最小化,以提升數字化團隊的效能和交付價值。
最後的最後,技術債務不能完全消滅,只能合理管控。
以上為學習:https://ieeexplore.ieee.org/document/9520328/ 論文的一些筆記,具體內容可參見原文。