技术团队,你欠了一屁股债你造吗?
1、究竟什么是技術(shù)債務(wù)?
技術(shù)債務(wù)是由團(tuán)隊為了短期的項目利益故意做了欠佳的技術(shù)決策而招致的。例 如,為了使一個產(chǎn)品更快的投放市場,團(tuán)隊可能不會像面對一段棘手的代碼那樣,編寫深入的自動化測試。或者,他們可能會決定基于一個很快就會過時的框架構(gòu)建 項目,而不是花錢購買那個框架的一個經(jīng)過升級、服務(wù)支持更好的版本。不管決策是什么,關(guān)鍵是要認(rèn)識到,真正的技術(shù)債務(wù)是團(tuán)隊為了獲得短期利益故意做了會招 致長遠(yuǎn)債務(wù)的決策。
這意味著,許多我們通常歸咎于 “技術(shù)債務(wù)” 的事情實際上根本就不是債務(wù)。例如,隨著系統(tǒng)使用年限增加,團(tuán)隊會無法一直保持最佳編碼實踐,在那種情況下出現(xiàn) “位衰減(bit dot)” 是正常的,不是債務(wù)。或者,團(tuán)隊自愿做出的技術(shù)決策在隨后實現(xiàn)時竟然發(fā)現(xiàn)是不正確的,這也不是技術(shù)債務(wù)。
在任何一種情況下,團(tuán)隊都不是為了獲得短期利益而故意做了欠佳的長遠(yuǎn)決策。這 種差別很重要,因為我們只有在究竟是什么組成了技術(shù)債務(wù)的問題上達(dá)成一致,我們才能針對如何減少技術(shù)債務(wù)做出最佳決策。考慮我們在無意間引入代碼庫的債務(wù) 所帶來的影響也很重要。不過,由于這類債務(wù)不是有意承擔(dān)的,所以我們無法計劃如何提前解決它。在這些情況下,我們一定要在發(fā)現(xiàn)的時候優(yōu)先考慮并解決這種債 務(wù)……就像團(tuán)隊解決新發(fā)現(xiàn)的 Bug 所做的那樣。
2、一個恰當(dāng)?shù)慕鹑诒扔?/p>
我們經(jīng)常將技術(shù)債務(wù)與金融債務(wù)進(jìn)行對比。但是,這是一個對等的類比嗎?比如,如果不首先確定何時以及如何償還,銀行真會愿意借給我們錢嗎?很可能不愿意。既然不首先描述如何償還債務(wù),我們就確實無法借到金融資本,那么我們也就不應(yīng)該以這種方式對待技術(shù)資本。這個金融比喻確實非常有效,因此,我們將對它進(jìn)行更充分的討論。
3、執(zhí)行嚴(yán)格的償還計劃
正如金融債務(wù)一樣,在談?wù)摷夹g(shù)債務(wù)時,我們需要確定兩件事:如何償還債務(wù)和何時償還債務(wù)。
如何償還債務(wù)?
讓我們以前文提到的放棄自動化測試為例。如果為了一項功能能夠盡快投入生產(chǎn)環(huán)境,我們的團(tuán)隊自愿決定放棄為棘手的代碼段編寫自動化測試,那么我們需要確定我們將如何糾正那塊債務(wù)。在這種情況下,我們只需要表明,我們會在將來的某個時點回到這段代碼,然后添加測試。
不過,只表明 “我們將在稍后添加測試” 并沒有合理地解決這個問題。為 了幫助干系人真正地了解我們的決策對招致技術(shù)債務(wù)會有多大的影響,我們需要盡我們最大的能力準(zhǔn)確地說明等到后來添加自動化測試的影響。比如,我們應(yīng)該指明 需要添加測試的代碼段。我們也需要明確指出,在已有的代碼段上增加自動測試比在代碼段創(chuàng)建時直接添加測試總是難度更大成本更高。最后這點很重要,因為它明 確指出,將這項工作推遲到后來完成,我們實際上要比現(xiàn)在直接完成花更多的錢來做這項工作。換句話說,……債務(wù)是會產(chǎn)生利息的。
在討論完償還方式之后,團(tuán)隊及其干系人可能會意識到,這個問題要比他們是否應(yīng)該在編寫代碼時編寫自動化測試更復(fù)雜。實際上,他們可能會發(fā)現(xiàn),在兩個極端之間,他們確實有多種更適合整個項目的選擇。比如,他們可能會決定,使用類似 “圈復(fù)雜度(Cyclomatic Complexity)” 這樣的指標(biāo)識別出新特性中最復(fù)雜的部分是非常有意義的,并立即添加測試覆蓋那些方面,而把簡單一些的方面推遲。或者,他們可能會決定,像單元測試這種更簡 單但同時價值也更低的自動化測試類型可以立即添加,但像自動化用戶驗收測試這種難度更高的自動化測試可以推遲到將來的沖刺中。不管是哪種決定,團(tuán)隊及其干 系人都不大可能做出,因為他們沒有在第一時間對技術(shù)債務(wù)進(jìn)行討論。
何時償還債務(wù)?
除了指明如何償還債務(wù)外,我們還希望指明何時償還債務(wù)。通常,債務(wù)越早償還越好。出 于這個原因,最好是在債務(wù)產(chǎn)生的時候安排債務(wù)償還工作,以便更好地傳達(dá)承擔(dān)債務(wù)的影響。比如,如果你的團(tuán)隊遵照一個由沖刺構(gòu)成的時間表,那么你可能會選擇 將工作安排到下一個沖刺,或者,在最壞的情況下也不超過幾個未來的沖刺。通常,團(tuán)隊都會有最美好的愿望,就是在債務(wù)出現(xiàn)的時候償還,但他們只是似乎從來都 沒有時間那樣做。當(dāng)你要消除債務(wù)的時候,在日歷上記下最后償還期限,并堅持按時完成。
4、避免違約的誘惑
對于我們的金融比喻,最后一部分是弄清楚,如果我們選擇拖欠債務(wù),會出現(xiàn)什么后果。在金融領(lǐng)域,如果我從來不償還汽車貸款,那銀行會開走我的汽車。拖欠技術(shù)債務(wù)的后果同樣應(yīng)該明確指出。讓我們繼續(xù)自動化測試的例子,如果團(tuán)隊決定不償還技術(shù)債務(wù),那么以現(xiàn)有的未經(jīng)測試的功能為基礎(chǔ)構(gòu)建新功能只會使難度越來越大成本越來越高。在 生產(chǎn)環(huán)境中,我們可能會看到更多的 Bug 報告,這意味著,客戶可能會對我們的產(chǎn)品質(zhì)量產(chǎn)生不好的印象。我們快速響應(yīng)市場變化的能力也會被削弱,因為我們產(chǎn)品的很大一部分要么很難快速修改,要么快 速修改風(fēng)險太大。上述各點都需要向干系人講清楚,幫助我們避開技術(shù)債務(wù)違約的誘惑。
5、困擾進(jìn)階——擺脫位衰減
截至目前,我們討論的所有內(nèi)容都集中在有計劃的技術(shù)債務(wù)上,就是那些作為正常項目的一部分團(tuán)隊故意招致的債務(wù),而如果我們不討論未計劃的技術(shù)債務(wù),我們就失職了,因為它們也困擾著許多項目:位衰減。如前所述,位衰減不是我們故意招致的,我們無法提前決定如何以及何時償還,在這個意義上,它不同于正常的技術(shù)債務(wù)。
不過,雖然我們無法確切地知道位衰減在我們項目中的呈現(xiàn)形式,但這并不意味著我們無法計劃它。就 像我們計劃償還已知技術(shù)債務(wù)時所做的那樣,我們也可以在我們的項目計劃中加入一個緩沖區(qū),用于在每次沖刺中處理位衰減。雖然那時可能并不知道填充這個緩沖 區(qū)的具體任務(wù),但有一個這樣的緩沖區(qū)在那里,使我們有了一個專門的空間,可以應(yīng)對那些未計劃的問題,如 Bug,必須立即處理的小規(guī)模重構(gòu),或者我們稱之為代碼庫自然老化和衰減的小塊系統(tǒng)維護(hù)。
但是,對于那些用幾個小時的開發(fā)時間都無法解決的更大的問題,該怎么辦?可 能會有更多讓我們倍感困擾的系統(tǒng)性問題,如基礎(chǔ)設(shè)施故障或架構(gòu)日益老化無法再滿足業(yè)務(wù)需求。由于這些問題太大,不容易解決,我們就可以使用這個緩沖區(qū)確認(rèn) 和研究這些問題,那樣,我們后續(xù)就可以在項目中給予它們應(yīng)有的注意。比如,在基礎(chǔ)設(shè)施故障的情況下,或許我們能夠確定基礎(chǔ)設(shè)施中最經(jīng)常出現(xiàn)故障的部分,那 樣我們就可以在待辦事項列表中增加故事,用于替換這些部分。然后,我們會在正常的開發(fā)中排定優(yōu)先級并照此調(diào)度那些故事。
或者,在架構(gòu)日益老化的情況下,我們可以花些時間來確定,我們對于架構(gòu)能夠動態(tài)做出的最有價值的修改是什么,然后將那些修改分解成可以在將來的沖刺中分段處理的故事。不管問題是什么,有時間確定問題并制定計劃就意味著可以像解決其它任何技術(shù)問題一樣解決它。
6、向預(yù)算擴(kuò)展
既然我們已經(jīng)對招致技術(shù)債務(wù)的影響有了一個更好的了解,那么我們該如何真正確保償還技術(shù)債務(wù)?為 了對此有一個感官的認(rèn)識,我們將上述金融比喻向另一個方向擴(kuò)展……預(yù)算。我們中有許多人每隔幾周就會掙得一份固定工資。這份工資是年度工資的一部分,全年 平均分布。比如,如果我們每年能掙 52000 美元,那么我們可能每隔 2 周就會收到 2000 美元……就是說,每年26 次。不過,雖然按規(guī)則我們每次都能領(lǐng)到 2000 美元工資,但我們實際上不大可能全部存放在活期賬戶上。相反,我們更可能只將一部分存放在活期賬戶上,而把其它部分用于長期投資或者償還債務(wù)。比如,我們 起初有 2000 美元存款,預(yù)算分解實際上可能是下面的樣子:
500 美元用于長期投資,比如存入退休賬戶
200 美元用于償還短期債務(wù),如信用卡
300 美元用于償還長期債務(wù),如按揭貸款或汽車貸款
250 美元直接扣除,用于支付地方或國家稅收
剩下的 750 美元存入活期賬戶
現(xiàn)在,雖然沒人對這種安排感到特別興奮,但也基本沒人質(zhì)疑。在某種程度上,它簡直是公認(rèn)的規(guī)范。既然這種安排被如此廣泛地接受,那么為什么不將它擴(kuò)展到我們的項目計劃中呢?想象一下,我們正以故事點為單位計劃一次沖刺,并且,我們?yōu)槟莻€沖刺分配了 50 個故事點。盡管我們希望將所有 50 個點都用在新的開發(fā)上,但實際上,最合理的方式是安排一些點用于償還技術(shù)債務(wù)。比如,對于原有的 50 個點,我們可能決定安排:
10 個點用于償還技術(shù)債務(wù)
5 個點用于不間斷的代碼庫維護(hù),如修復(fù) Bug 或處理位衰減
35 個點用于新的開發(fā)
看 看我們的點預(yù)算,我們可以看到它與我們前面描述的金融預(yù)算有一些明顯的相似之處。雖然每個沖刺我們有 50 個點用來做事,但并不是所有那些點都用在新的開發(fā)上。更確切地說,我們必須把那些點中的 10 個用于償還我們有意招致的技術(shù)債務(wù),正如我們把工資的一部分用于償還我們的長期和短期債務(wù)。此外,我們將 5 個點完全用于保持不間斷的代碼庫維護(hù),正如我們把每份工資的一部分用于稅收,幫助維持我們社區(qū)的正常運轉(zhuǎn)。剩下的點是我們自己的,可以根據(jù)我們的意愿用于 任何新的開發(fā),正如剩下的錢存入活期賬戶,我們可以根據(jù)自己的意愿自由支配。
通過工作預(yù)算的方式,我們可以確保我們的項目仍然在向前進(jìn)行,而不允許它在技術(shù)債務(wù)的重壓之下崩潰。當(dāng) 然,就像個人預(yù)算一樣,這種預(yù)算會有些偏差。比如,如果我們償還技術(shù)債務(wù)的速度比預(yù)期快,那么我們就會有些剩余的故事點可以用在新功能開發(fā)上。而同樣的, 如果我們發(fā)現(xiàn)我們承擔(dān)著特別多的技術(shù)債務(wù),那么我們可能需要稍微降低新功能的開發(fā)速度,直到技術(shù)債務(wù)的數(shù)量回到一個更可控的水平。
7、小結(jié)
通 過以金融債務(wù)做類比考慮技術(shù)債務(wù),我們可以對什么時候會招致技術(shù)債務(wù)有一個更明智的判斷,有利于項目改善。在項目進(jìn)行過程中,我們還可以更好地計劃試圖償 還債務(wù)所帶來的影響。同時,通過在日常工作中計劃日常預(yù)算,我們可以更好地了解我們的債務(wù)什么時候是可控的以及什么時候會讓我們負(fù)擔(dān)過重。
====================================分割線================================
文章轉(zhuǎn)載自 開源中國社區(qū)[http://www.oschina.net]
總結(jié)
以上是生活随笔為你收集整理的技术团队,你欠了一屁股债你造吗?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2016 年 Linux 领域的十大新闻
- 下一篇: 特别的字节对齐问题