天天看點

從整體組織的角度看待技術債,避免技術破産

作者 | Einar H st

譯者 | 劉雅夢

策劃 | 丁曉昀

随着軟體系統的不斷發展,它們往往會變得不那麼靈活,也更難使用。我們通常把這種情況歸咎于猖獗的“技術債”,但卻沒有讨論導緻技術債的原因。

笨拙的程式設計不是造成技術債的主要原因,是以我們不能指望僅依靠更熟練的程式設計就能解決技術債。相反,技術債是溝通不暢的三階效應。這是缺乏适當抽象的症狀,而這反過來又源于對問題領域模組化的不足。這意味着沒有進行充分的溝通;為解決歧義并做出明智的權衡而進行的讨論和決策已經被掩蓋了。

我們所觀察到并被标記為“技術債”的是這一功能失調開發過程的副産品:代碼中缺乏解決方案的具體化。為了解決不斷積累的技術債問題,我們需要修複這個被破壞的過程。

造成技術債的主要原因

技術債的比喻是由 Ward Cunningham 引入的,它用來描述開發人員有意識地決定将具有已知限制的代碼傳遞到生産環境中的過程。提前傳遞的目的有兩個:快速進入市場,以及實作從生産到進一步開發和改進的回報循環。它很快就流行起來了,因為它允許開發人員通過技術解決方案将“看不見的”問題傳達給管理層和其他利益相關方。

然而,在技術債這個比喻變得廣泛而流行的過程中,它的含義也被稀釋了。在生産環境中運作的任何有局限性或者存在品質問題的代碼都可能會被貼上技術債的标簽。這是不幸的,因為它破壞了比喻的實用性和豐富性。很多被認為是技術債的東西都是随着時間的推移而無意中産生的,并且沒有明确的償還政策。

技術破産

令人遺憾的是,技術債這個比喻的含義已經被以這種方式稀釋了,但是在語言中,就像在生活中一般,實用主義勝過意圖。這就是我們的處境:所謂的“技術債”在很大程度上隻是正常軟體開發的副産品。當然,沒有人希望代碼問題以這種方式累積,是以問題就變成了:為什麼我們似乎總會無意中導緻如此多的技術債呢?我們進行軟體開發的方式是什麼樣的,它為什麼會導緻這種我們不想要的結果呢?

這些問題很重要,因為如果我們陷入了技術債,那麼我們就會在技術上資不抵債并在技術上破産。事實上,這似乎是許多軟體開發工作中正在發生的事情。Ward Cunningham 指出,“整個工程組織可能會因為未整合實施的債務負擔而停滞不前”。這種停滞就是技術性的破産。這意味着你的組織無法再繼續前進了。

對軟體進行合理的變更需要花費不合理的時間來實作。品質問題就成了永久性的問題;如果沒有引入新 bug 的機會,就無法修複 bug,進而導緻問題之間的某種共振。

實踐中的技術債

如果我們要了解無意中導緻技術債積累的力量,我們必須要看下代碼,并看看“技術債”是如何展現出來的。

我的觀察結果是,代碼中往往有很多的“如果”和“但是”,但很少能傳達意圖并幫助了解。我的意思是,代碼中有許多 和 分支,還有大量的布爾标志來控制這些分支之間的執行流。缺少的是能了解這一切的有用抽象和邊界。這使得隔離出與單個功能相關的代碼變得十分困難,因為該功能的代碼在任何意義上(或明顯意義上)來說都不是孤立的。很難預測變更後的影響,因為變更某個布爾标志可能會在整個代碼庫中産生連鎖反應。

當我們對我們試圖用軟體來解決的問題有了一個不成熟且不充分的心智模型時,代碼的結果是這樣的。軟體肮髒的秘密在于,我們可以對我們無法清晰表達的問題實施解決方案。如果我們的軟體是“錯誤的”,那麼正确的行為總是隻需一個 分支。我們隻需要用某種方法來注入正确的标志,就可以在執行流中轉向正确的行為,而非錯誤的那個。在實作中,我們确實可以通過使用 分支來補償我們糟糕的領域模型。但這正是我們因疏忽而造成技術債問題的原因:随着時間的推移,我們把自己逼到了絕境。它使軟體變得難以了解了——技術破産。

在不破壞現有功能的情況下,我們不能再以這種方式添加功能了。

修複模式,而不是代碼

如果我們的頭腦中沒有正确的概念,就很難寫出簡單而又精确的代碼。我們不僅需要這些概念來建構我們的解決方案,而且需要在一開始時就能清楚地思考這個問題。隻要我們缺乏正确的概念,我們的思維以及我們與他人的交流就會變得笨拙而迂回。想象一下,在不知道狗(dog)這個單詞或者甚至不知道動物(animal)這個單詞的情況下,試圖給某人講一個關于狗的故事。“它是一種急切的、搖尾巴的、有四條腿的生物”。這聽起來很傻,但我在項目中多次遇到這種情況。

在我參與的一個項目中,我們在處理信用卡子產品時遇到了困難。代碼複雜且難以了解,而且每當我們談到這個子產品時,我們的讨論效率就會變得很低且令人沮喪,但我們無法真正弄清楚原因。直到我們意識到我們缺乏一個概念來描述信用卡是如何與信用卡交易相關聯的(一種“關聯機制”),才使得一切變得合理。突然間,我們的頭腦清醒了,我們的讨論也清晰了,而且我們可以非常直接地實施它。我們删除了我們之前所編寫的所有笨拙的代碼,并代之以一些簡單易懂的代碼。

這一經驗為處理複雜代碼提供了一種啟發式的方法;為那些往往會在一段時間後被貼上“技術債”标簽的代碼尋找缺失或尴尬的概念。在團隊的設計讨論中尋找受挫的模式。可能是領域想告訴你一些事情。試圖“修複”沒有正确概念的代碼很可能會失敗,因為錯誤的概念沒有優雅或幹淨的組織。

我想說的是,我們的問題是源于我們試圖用軟體來解決的問題具有不成熟且不充分的心智模型。對于團隊協作開發的軟體來說(也就是大多數的軟體),該心智模型需要在軟體開發人員之間共享。不然的話,毫無疑問,不一緻和極端情況就會咬着我們不放。如果我們沒有就問題和建議的解決方案達成一緻的話,那麼我們應該期望看到這些對齊失敗的後果能在代碼中展現出來。我們也确實是如此。

開發一個足夠豐富且靈活的共享心智模型的關鍵是溝通和協作。當軟體被技術債壓得喘不過氣來時,這表明開發軟體的組織可能需要檢視其溝通和協作模式了。

業務與 IT 之間的分歧

Ward Cunningham 發明了“技術債”這個比喻,使得開發人員能夠與業務人員交流一些前者看得見、後者看不見的東西;雖然我們現在釋出的代碼滿足了業務需求,但我們在這方面做得太多了。這樣做讓我們失去了平衡,我們需要花一些時間來恢複這種平衡。否則我們最終會摔倒,很難再爬起來。但從某種意義上說,這是一個很容易解決的問題:可以說,慷慨地給開發人員一點時間,讓他們時不時地打掃一下自己的房子。業務人員所需要的隻是一點等待開發人員迎頭趕上的耐心。

不幸的是,我認為這不會奏效。如果我的觀點是正确的,即我們所說的技術債實際上是源于業務領域模組化的不足,并且最終是由溝通和協作問題引起的,那麼這不是開發人員可以自行解決的問題。事實上,認為開發人員能夠并且應該單獨處理技術債是導緻技術債的另種思維症狀。對于開發人員和業務人員來說,這都是一個令人不安的觀點。對于業務人員來說,将技術債視為 IT 需要處理的事情是很友善的,而對于開發人員來說,認為他們所需要的隻是一點時間來把事情做好就更舒服了。但如果我們要解決技術債的根本原因,這是一種我們無法承受的便利和安慰。

減少技術債

對于一個發現自己正接近技術破産的軟體組織來說,主要的問題不是債務本身,而是該組織在其目前狀态下無意中産生了大量難以管理的複雜代碼。如果我們繼續以與以前相同的速度産生新的債務,那麼削減已發生的債務幾乎沒有任何用處。試圖理清瀕臨破産的代碼可能是非常昂貴、耗時和冒險的。通常,最好是找到某種方法,用其他以更健康的方式生成的代碼來替換債務繁重的代碼。我能給出的最好的建議是盡量減少我們目前的債務,也就是說,首先要減少我們必須要減少的技術債。

随着時間的推移,減少我們所謂的“技術債”的最佳方法是解決根本原因,那就是我們如何共同協作的方式。改變軟體組織的文化可能很困難。自上而下的舉措往往會遇到困難,因為它們無法解決實地出現的問題。也許最好的自上而下的舉措是給那些處于底層的人留出餘地和自主權,因為我相信自下而上是有可能帶來積極改變的。

我的經驗是,作為一個團隊進行軟體開發(即內建程式設計)不僅可以更快地為問題提供更好的設計解決方案,而且還可以創造一種向更開放、更具同理心和更坦誠的溝通文化的轉變。這反過來意味着,随着時間的推移,進行內建程式設計的團隊不太可能會陷入技術債的泥潭中。此外,在經曆了團隊内部溝通的改善之後,團隊成員也不太可能适應跨團隊邊界或組織中不同角色的人員之間的溝通不暢。如果這是真的,那麼團隊合作可以對組織的溝通模式産生積極的連鎖反應。

結 論

在軟體行業中,無意中不斷積累不受控制的技術債是一種普遍現象。造成這種趨勢的根本原因是我們的溝通模式不夠完善。這導緻了心智模型的不成熟,開發人員通過堆積布爾标志和分支控制流來近似解決表達和了解欠佳的問題。

随着時間的推移,以這種方式建構的軟體變得難以了解。打破這種趨勢的方法是改變我們建構軟體的方式:通過更好的協作和交流。正在內建的工作可能會朝着正确方向邁出一大步,因為它将協作和溝通置于軟體開發的核心了。

作者介紹:

Einar W. H st是挪威公共廣播公司 NRK 的軟體開發人員,在該公司,他幫助建立了電視流媒體服務。他的主要興趣是領域模組化、API 設計和計算機程式設計。他擁有奧斯陸大學計算機科學博士學位。你可以在推特上 @einarwh(https://twitter.com/einarwh) 找到他,或者讀 他的部落格 (https://einarwh.wordpress.com)。

https://www.infoq.com/articles/avoiding-technical-bankruptcy/

繼續閱讀