聊一下,技術(shù)債務(wù)治理
前言
在現(xiàn)代軟件開發(fā)中,技術(shù)債務(wù)(Technical Debt)已成為一個(gè)不可忽視的重要概念。它指的是在軟件開發(fā)過程中,為了追求短期目標(biāo)而做出的妥協(xié),導(dǎo)致未來需要付出額外成本來修復(fù)這些妥協(xié)所帶來的問題。技術(shù)債務(wù)的管理不僅影響項(xiàng)目的質(zhì)量和可維護(hù)性,還直接關(guān)系到團(tuán)隊(duì)的工作效率和公司的長期發(fā)展。
什么是技術(shù)債務(wù)?
技術(shù)債務(wù)的定義可以追溯到Ward Cunningham,他將其比喻為“借款”,即在軟件開發(fā)中選擇了一個(gè)較為簡單的解決方案,而非最佳實(shí)踐。這種選擇雖然在短期內(nèi)能加快開發(fā)進(jìn)度,但卻可能在未來導(dǎo)致更高的維護(hù)成本和更復(fù)雜的技術(shù)問題。
圖片
為了提升需求開發(fā)速度,我們有時(shí)會(huì)在應(yīng)當(dāng)采納最佳方案時(shí)作出妥協(xié),轉(zhuǎn)而選擇那些短期內(nèi)能迅速推進(jìn)項(xiàng)目進(jìn)程的方案。然而,這種做法往往會(huì)導(dǎo)致未來的錯(cuò)誤問題增多,并給自己帶來額外的開發(fā)負(fù)擔(dān)。這種技術(shù)層面的抉擇,猶如背負(fù)了一筆債務(wù)。
技術(shù)債務(wù)的分類
同樣,技術(shù)債務(wù)也有其層次之分,通常根據(jù)其影響程度和解決的緊迫性,我們可以將其劃分為四個(gè)象限,即技術(shù)債務(wù)的四象限模型。
圖片
技術(shù)債務(wù)可以根據(jù)不同的標(biāo)準(zhǔn)進(jìn)行分類:
有意和無意兩種:
有意技術(shù)債務(wù):團(tuán)隊(duì)明確意識(shí)到當(dāng)前的解決方案并非最佳選擇,且計(jì)劃在未來進(jìn)行改進(jìn)。
無意技術(shù)債務(wù):團(tuán)隊(duì)在缺乏足夠信息或經(jīng)驗(yàn)的情況下做出的選擇,往往潛伏較久,難以察覺。
魯莽型和謹(jǐn)慎型:
魯莽技術(shù)債務(wù):由于缺乏規(guī)劃和規(guī)范而產(chǎn)生的債務(wù),通常會(huì)導(dǎo)致嚴(yán)重的后果。
謹(jǐn)慎技術(shù)債務(wù):在項(xiàng)目進(jìn)度中做出的合理妥協(xié),雖然存在風(fēng)險(xiǎn),但在可控范圍內(nèi)。
技術(shù)債務(wù)全景圖
根據(jù)卡內(nèi)基-梅龍大學(xué)軟件工程研究所(SEI)的Robert Nord在《The Future of Managing Technical Debt》中提出的“技術(shù)債務(wù)全景圖”,技術(shù)債務(wù)可以從多個(gè)維度進(jìn)行分析:
圖片
這張全景圖清晰地展現(xiàn)了技術(shù)債務(wù)的多個(gè)層面,包括那些通常與架構(gòu)相關(guān)聯(lián)的債務(wù)、因環(huán)境變化而產(chǎn)生的技術(shù)差距型債務(wù),以及主要由內(nèi)部代碼質(zhì)量低下引起的小粒度技術(shù)債務(wù)。
此外,通過這張圖,我們還可以洞察到兩個(gè)重要的方向。
可演進(jìn)性
本質(zhì)上,架構(gòu)的元特征描述的是軟件架構(gòu)在演進(jìn)過程中趨于目標(biāo)的能力。這種演進(jìn)目標(biāo)并不僅限于支撐功能快速迭代的靈活性,同樣可以涵蓋其他重要的架構(gòu)屬性,如高可用性和可擴(kuò)展性。
可維護(hù)性
狹義上的代碼問題主要涉及代碼的易理解性、問題的易修復(fù)性,以及在現(xiàn)有基礎(chǔ)上的易擴(kuò)展性。這些因素共同影響著代碼的質(zhì)量和可維護(hù)性。
背景
當(dāng)技術(shù)債務(wù)已經(jīng)嚴(yán)重影響了公司的運(yùn)作、工作的效率時(shí),才會(huì)著手去處理這些方面的問題,可要付出的代價(jià)就太大了。
圖片
隨著滴滴國際化業(yè)務(wù)的快速發(fā)展,技術(shù)棧的多樣化使得技術(shù)債務(wù)的管理變得愈發(fā)復(fù)雜。當(dāng)前,研發(fā)所需的語言已不僅局限于平臺(tái)原生語言,跨平臺(tái)技術(shù)(如Flutter及其Dart語言)逐漸成為主流。這一轉(zhuǎn)變帶來了新的技術(shù)債務(wù)挑戰(zhàn),尤其是在代碼質(zhì)量和架構(gòu)設(shè)計(jì)方面。
演繹過程
在項(xiàng)目的初期階段,我們面臨著快速上線和快速迭代的壓力,因此問題的積累是不可避免的。然而,隨著我們的不斷發(fā)展,我們意識(shí)到如果繼續(xù)這種狀態(tài),將會(huì)對項(xiàng)目的質(zhì)量和成本帶來雙重風(fēng)險(xiǎn)。同時(shí),隨著業(yè)務(wù)逐漸融入Flutter跨平臺(tái)能力,我們在學(xué)習(xí)和研發(fā)Flutter的過程中,也遇到了諸多挑戰(zhàn)。特別是隨著Flutter SDK的不斷升級,我們在這個(gè)過程中也積累了大量的技術(shù)債務(wù),例如空安全適配問題。目前,我們的SDK版本支持2.12.0,這是一個(gè)允許空安全和非空安全混合的版本,因此存在很大的隱患。
影響分析
對開發(fā)的影響
也許某一天我們接收了一個(gè)陌生的模塊,也許是自己曾經(jīng)的代碼,發(fā)現(xiàn)如同屎山一樣,如下圖,自己都看不懂了,為了應(yīng)付快速迭代的需求,只能不停的往這上面堆,這個(gè)屎山也會(huì)愈發(fā)龐大和混亂,如果這樣繼續(xù)下去,知道某一天因?yàn)橐粋€(gè)小小的Bug,你需要花半天的時(shí)間來排查問題出在哪里,最后當(dāng)你覺得問題終于改好了的時(shí)候,卻不料碰了不該碰的地方,結(jié)果就是 fixing 1 bug will create 10 new bugs,甚至程序的崩潰。
我們需要正確面對、積極面對這個(gè)事情,它不是沒有技術(shù)含量,他能給我們帶來更多的技術(shù)和業(yè)務(wù)上的挑戰(zhàn)。
對效率的影響
技術(shù)債務(wù)的治理本質(zhì)上是提升效率的過程。
治理不當(dāng)將導(dǎo)致開發(fā)周期延長、資源浪費(fèi)和團(tuán)隊(duì)士氣下降。因此,及時(shí)識(shí)別和解決技術(shù)債務(wù)是確保項(xiàng)目成功的關(guān)鍵。
圖片
現(xiàn)狀梳理
業(yè)務(wù)發(fā)展至今,通過整理存量問題和結(jié)合監(jiān)控報(bào)警沉淀的問題,可以看出目前工程存在的問題方向。(非最全)
圖片
代碼復(fù)雜
在快速迭代過程中,往往忽視了良好的代碼組織與模塊化設(shè)計(jì),導(dǎo)致組件間出現(xiàn)高度耦合的現(xiàn)象。此外,類文件行數(shù)過長也是一個(gè)需要關(guān)注的問題。這些問題可能會(huì)影響代碼的可讀性和可維護(hù)性,進(jìn)而降低開發(fā)效率。因此,我們需要重視代碼結(jié)構(gòu)的優(yōu)化和模塊化設(shè)計(jì),以降低組件間的耦合度,并合理控制類文件行數(shù),從而提高代碼質(zhì)量。
架構(gòu)混亂
- 業(yè)務(wù)架構(gòu)在從初期到后期的迭代過程中,經(jīng)歷了逐步分化和嘗試等階段,尚未形成統(tǒng)一的結(jié)構(gòu)走勢。
- 目前存在新舊架構(gòu)混合使用的情況。
代碼風(fēng)格
在Flutter跨平臺(tái)代碼中,代碼結(jié)構(gòu)和規(guī)范風(fēng)格的不統(tǒng)一是一個(gè)常見問題。這主要是由于不同IDE的使用,很容易引發(fā)代碼風(fēng)格上的沖突,進(jìn)而帶來潛在的風(fēng)險(xiǎn)。為了提高代碼的可讀性和可維護(hù)性,降低風(fēng)險(xiǎn),我們需要確保在整個(gè)代碼庫中保持一致的代碼結(jié)構(gòu)和規(guī)范風(fēng)格。
基建混亂
在業(yè)務(wù)組件基建和服務(wù)基建方面,由于缺乏統(tǒng)一的最佳實(shí)踐范式,導(dǎo)致使用層的代碼出現(xiàn)混亂。這一問題亟待解決,以確保代碼的整潔性和可維護(hù)性。
工程效率
管理缺乏統(tǒng)一性,功能分散,導(dǎo)致功能可用性低下。
性能債務(wù)
- 解決由持續(xù)SDK升級觸發(fā)的報(bào)警問題
- 優(yōu)化內(nèi)存管理
- 清理未使用的資源和已下架的代碼
- 實(shí)施lint代碼質(zhì)量檢查與治理
- 進(jìn)行空安全適配(針對Flutter框架)
目標(biāo)
產(chǎn)物目標(biāo)
一套簡易可視化運(yùn)營平臺(tái)
- 結(jié)合Lean平臺(tái),對Lean平臺(tái)錄入信息,通過腳本產(chǎn)出自定義報(bào)告。
- 增加巡檢能力,周頻次跟進(jìn)問題狀態(tài)。
穩(wěn)定性目標(biāo)
沉淀問題,整合債務(wù)
通過深入剖析問題和細(xì)致整合債務(wù),將技術(shù)債務(wù)治理提升為確保系統(tǒng)穩(wěn)定性的關(guān)鍵環(huán)節(jié)。
質(zhì)量目標(biāo)
提高代碼質(zhì)量
- 提高代碼質(zhì)量,確保代碼符合Lint標(biāo)準(zhǔn)。
- 完成Flutter的空安全適配。
面對挑戰(zhàn)
業(yè)務(wù)挑戰(zhàn)
- 穩(wěn)定性的設(shè)計(jì)需要針對老業(yè)務(wù)流程進(jìn)行二次梳理,如何保證線上穩(wěn)定性是關(guān)鍵。
- 在需求中不斷植入Fix的問題,確保技術(shù)債務(wù)的及時(shí)解決。
技術(shù)挑戰(zhàn)
- 優(yōu)化思路和設(shè)計(jì)需要更全面的考慮。
- 如何通過架構(gòu)設(shè)計(jì)更完美地落地修改和重構(gòu)。
- 對技術(shù)的深入理解是實(shí)現(xiàn)更好方案的基礎(chǔ)。
治理方案
債務(wù)整體架構(gòu)
圖片
方向:通過對當(dāng)前問題的歸納,合理劃分技術(shù)債務(wù)的治理方向
- 業(yè)務(wù)架構(gòu):主要以業(yè)務(wù)代碼實(shí)現(xiàn)為主,最佳范式等;
- 基建:對接底層基建能力,使用上不合理不舒服的點(diǎn)。
- 代碼:實(shí)施代碼規(guī)范、Lint治理和代碼格式化。
- 效能:所有輔助程序運(yùn)行的腳本能力。
治理運(yùn)營:一套可持續(xù)運(yùn)行的方案
任何人不管問題的大小,都可以暢快的提出問題(不是誰提出誰修改,你只管提),把痛點(diǎn)問題進(jìn)行描述,通過Lean平臺(tái)記錄,并會(huì)有專門的人(提出人)標(biāo)記方向(分類),負(fù)責(zé)的同學(xué)或者感興趣的同學(xué)都可以進(jìn)行認(rèn)領(lǐng),并做出合理的方案和同步進(jìn)度。
沉淀:
通過這些點(diǎn)沉淀能力,不斷的下沉能力,解耦業(yè)務(wù)。
建設(shè):
- 非開源:可以按照產(chǎn)物進(jìn)行成果分享。
- 開源:是最好的狀態(tài),開源我們一些厲害的能力,無論是什么方向的結(jié)果。
債務(wù)治理機(jī)制
為了解決這些問題,我們決定采取一系列措施來優(yōu)化我們的項(xiàng)目和技術(shù)棧,并最終沉淀出一套我們可執(zhí)行可長期運(yùn)營的方案。
圖片
識(shí)別
- 技術(shù)的持續(xù)改進(jìn)離不開團(tuán)隊(duì)中每個(gè)人的努力,因此需要每個(gè)成員都積極參與。在日常交付中,團(tuán)隊(duì)成員應(yīng)該持續(xù)識(shí)別和記錄需要改進(jìn)的問題并將其放入Lean平臺(tái)中,以便在技術(shù)改進(jìn)會(huì)議中與團(tuán)隊(duì)同步。
- 此外,團(tuán)隊(duì)還可以定期組織頭腦風(fēng)暴,以收集技術(shù)痛點(diǎn)和改進(jìn)建議。
可視化平臺(tái)
通過一個(gè)共享平臺(tái),我們可以高效地錄入和展示信息,從而更清晰地一覽所有問題的分布情況和各類問題的占比。這樣的設(shè)計(jì)不僅提升了工作效率,還使得數(shù)據(jù)分析更加直觀、便捷。
優(yōu)先級
我們時(shí)常會(huì)遇到的問題是,需要改進(jìn)的地方太多,尤其是對于遺留系統(tǒng)。怎么辦?先排優(yōu)先級。我們可以基于價(jià)值/成本矩陣來評估改進(jìn)任務(wù)的價(jià)值和成本。
圖片
基于矩陣:
- 優(yōu)先解決高價(jià)值+低成本的技術(shù)債。
- 嘗試將高價(jià)值+高成本的技術(shù)債拆分為高價(jià)值+低成本的技術(shù)債,“盡早、頻繁、小批”地進(jìn)行PDCA(Plan/Do/Check/Adjust)的迭代解決。
- 在沒有高價(jià)值+高/低成本的技術(shù)債時(shí),再來考慮低價(jià)值+低成本的技術(shù)債。
- 最后如果只剩下低價(jià)值+高成本的技術(shù)債,還是先拆分,再解決,或可考慮直接移除。
執(zhí)行
債務(wù)問題,是無法集中清理的,每個(gè)人每天都有自己的業(yè)務(wù)需求,所以我個(gè)人認(rèn)為可以存在兩個(gè)進(jìn)度方式:
- 在版本跌在中,引入20%的工作量進(jìn)行技術(shù)任務(wù)的改進(jìn)。
- 在技術(shù)架構(gòu)升級或者重構(gòu)等方案中,評估債務(wù)任務(wù)的清理。
總結(jié)&公式
- 每周固定時(shí)間進(jìn)行報(bào)告產(chǎn)出。
- 存在這個(gè)能力,就能更好的整體觀測治理的大盤,有助于促進(jìn)治理的節(jié)奏,不會(huì)石沉大海。
- 讓債務(wù)問題成為一個(gè)話題榜,成為一個(gè)論壇貼。從枯燥變成一種可持續(xù)輸出知識(shí)點(diǎn)的平臺(tái)。
我認(rèn)為在技術(shù)債務(wù)管理中,這一步是很重要的,我們需要分享解決的思路和成果,它是具有價(jià)值的,分享的過程是信息同步也是團(tuán)隊(duì)認(rèn)知的對齊。
圖片
總結(jié)
通過這套精心設(shè)計(jì)的治理機(jī)制,我們能夠高效地對問題進(jìn)行細(xì)致分類,并實(shí)現(xiàn)有條不紊的治理。結(jié)合先進(jìn)的可視化平臺(tái)Lean+報(bào)告產(chǎn)出平臺(tái),我們可以實(shí)時(shí)追蹤問題的處理進(jìn)度。這一機(jī)制不僅幫助我們成功解決了問題,還促進(jìn)了寶貴知識(shí)的積累和共享,形成了豐富的知識(shí)庫。
穩(wěn)定性方向沉淀
公司層面一直在推進(jìn)穩(wěn)定性,通過事前、事中、事后三個(gè)階段進(jìn)行預(yù)防、監(jiān)控、復(fù)盤總結(jié),形成一個(gè)閉環(huán)流程。
圖片
在技術(shù)債務(wù)治理方面,我認(rèn)為它扮演著事前過濾器的重要角色。通過運(yùn)用技術(shù)債務(wù)治理的手段,我們可以有效地識(shí)別并處理許多潛在隱患,從而為系統(tǒng)的穩(wěn)定性奠定堅(jiān)實(shí)基礎(chǔ)。
在整體穩(wěn)定性的三個(gè)階段中,事中和事后階段能夠持續(xù)揭露技術(shù)債務(wù)問題的多維面貌,并對其進(jìn)行系統(tǒng)歸納與整理。這些寶貴的經(jīng)驗(yàn)教訓(xùn)隨后被轉(zhuǎn)化為事前階段的預(yù)防性過濾網(wǎng),從而助力我們更加精準(zhǔn)地預(yù)防和應(yīng)對未來潛在的問題挑戰(zhàn)。
總結(jié)
在事中、事后階段,我們要能夠及時(shí)發(fā)現(xiàn)并沉淀歸納債務(wù)問題,確保問題留痕、總結(jié)到位,并達(dá)成共識(shí),以便更出色地完成事前規(guī)劃的任務(wù)。
代碼質(zhì)量治理
lint治理
從此時(shí)此刻起:債務(wù)問題不再新增,趨勢線逐步下降;
嚴(yán)格執(zhí)行代碼規(guī)范、CR機(jī)制、Dlinter統(tǒng)一規(guī)范,提交高質(zhì)量代碼。
圖片
工程配置規(guī)則、遠(yuǎn)程代碼配置規(guī)則開啟,自動(dòng)reject。(Flutter 配置為主)
圖片
空安全適配(Flutter)
我們強(qiáng)烈建議你按順序遷移代碼,先遷移依賴關(guān)系中的處于最末端的依賴。例如,如果 C 依賴了 B,B 依賴了 A,那么應(yīng)該按照 A -> B -> C 的順序進(jìn)行遷移。
圖片
遷移時(shí)序?qū)?/strong>
從底層服務(wù)類出發(fā),逐層向上適配。
圖片
總結(jié)
技術(shù)債務(wù)是項(xiàng)目進(jìn)程中難以避免的現(xiàn)象,然而,如何將其控制在可管理范圍內(nèi),卻是我們必須深思的問題。要想有效預(yù)防和化解技術(shù)債務(wù),離不開優(yōu)秀開發(fā)人員的貢獻(xiàn),而團(tuán)隊(duì)的協(xié)同合作更是至關(guān)重要。借助這套精心設(shè)計(jì)的治理機(jī)制,我們能夠?qū)Ω黝悊栴}進(jìn)行科學(xué)分類和有序治理。同時(shí),結(jié)合高效的可視化平臺(tái),我們可以實(shí)時(shí)追蹤問題進(jìn)展,不僅及時(shí)解決現(xiàn)有問題,還能在此過程中積累并提煉出大量寶貴的共享知識(shí)資源。
結(jié)論
技術(shù)債務(wù)在現(xiàn)代軟件開發(fā)中屢見不鮮,然而,借助高效的治理策略與團(tuán)隊(duì)的協(xié)同合作,我們完全有能力將其潛在影響壓縮至最小。不懈的學(xué)習(xí)與持續(xù)的改進(jìn)乃是項(xiàng)目取得成功的基石,唯有如此,我們方能在日新月異的技術(shù)浪潮中穩(wěn)立潮頭,保持強(qiáng)勁的競爭力。
技術(shù)債務(wù)是一個(gè)普遍存在的問題,它不受平臺(tái)或編程語言的限制。我們應(yīng)該共同努力,不斷學(xué)習(xí)和提升自己,以應(yīng)對這一挑戰(zhàn),共同推動(dòng)技術(shù)進(jìn)步。