做者:Isha Tripathi微信
翻譯:老齊markdown
與本文有關的圖書推薦:《跟老齊學Python:Django實戰(第二版)》工具
想象下面的場景:oop
這是一個黑暗的暴風雨之夜。閃電每隔幾分鐘就會劃破天空。在遠處,你能夠看到一大堆幾年前寫的代碼。這些代碼大部分都被做者遺忘了,甚至找不到做者。你當心翼翼地接近它,殊不知道從哪裏開始。你惴惴不安地決定從某一處開始,不知道你的勇敢會給團隊帶來什麼樣的災難。單元測試
若是這個場景不適合你,那麼請想象下面的場景:測試
在一種叫作層層疊的益智類遊戲中, 每一層都在另外一層上保持不穩定的平衡。只要有一個倉促的動做,整座塔就倒塌了。spa
這正是處理遺留代碼的感受。讓我首先描述一下我所說的「遺留」代碼。我指的是:翻譯
源代碼來自其餘人和(或)源代碼來自舊版的程序。設計
之因此繼承,一般是由於你(做爲公司或開發人員)須要接手另外一個公司或開發人員編寫的代碼,而且須要擴展和維護上述代碼庫。我將要在這篇文章中討論使用遺留代碼的兩方面的問題:code
我在使用遺留系統時遇到的一個常見問題是缺乏測試。即便有測試的話,也不多有單元測試,也許還有一些集成或功能級別的測試——這些測試大部分都是過後進行的,而不是對代碼進行實際的保護。大多數測試或全部測試只會涉及基本邏輯的場景,而且會忽略系統中的邊緣狀況。
這自己可能不是一個嚴重的問題,但隨着系統的發展和開發人員的輪換,問題就出現了。人們愈來愈難以追蹤這些變化對系統形成的影響,由於就寫了一些孤立的東西或者使用了全局變量等等,這使得代碼必須高度依賴「熟悉系統」的人。
毋庸置疑,並非每一個問題均可以經過增長代碼覆蓋率和進行更多測試來解決,但它確實有助於消除一些風險。咱們都但願確保對系統的任何更改不會影響現有功能,更普遍的測試覆蓋範圍剛好有助於此。此外,更多的單元測試能夠確保在較低的級別捕獲邏輯問題,從而更容易識別出有問題的代碼。
在一個理想的世界中,任何系統都將遵循測試金字塔——大量的單元測試,一些服務測試和較少的UI/功能測試。
然而,對於你可能遇到的大多數遺留代碼庫,測試金字塔可能看起來像這樣:
當第一次使用相似於以上圖像的遺留代碼庫時,一個常見的誤區是試圖當即開始編寫單元測試。雖然目的是很是難得的,但這也意味着你在那個時候不會創造任何業務價值。對於沒有看到向系統中添加功能價值的客戶來講,更難證實你這樣作的意義。
一個更有效的方法是,首先爲你所接觸的任何一段代碼或你所添加的新代碼編寫測試。這將有助於你找到一箇中間地帶,這種作法叫作紙杯蛋糕模式。
注:紙杯蛋糕模式被視爲反模式,由於相同數量的信息是在多個層次上測試的。然而,與傳統(遺留)的代碼庫相比,這更適用於綠地代碼庫。若是你從頭開始一個項目,絕對應該避免這種模式。在傳統的代碼庫中,正是這種迫切須要但並不理想的中間地帶,幫助鋪平了通往理想狀態的道路。
隨着時間的推移,你對系統更加熟悉了,就能夠繼續在全部級別添加測試,並對你的項目實現一個可接受的測試金字塔。
我遇到過這樣的狀況:開發人員很是不肯意升級到新版本的庫,由於引入的更改會形成破壞;或者因爲擔憂破壞系統而繼續使用過期的工具和技術來編寫項目。
這些擔憂是徹底正確的,絕對值得考慮。然而,人們必須記住,使用過期的工具和庫會形成的反作用。這些反作用可能會在最不經意的時候累積起來,並咬傷你。舊的工具一般再也不受支持,並且很難找到問題的答案。還有一個事實是,隨着時間的推移,你的需求會發生變化,在某些時候,過期的工具將再也不知足你的需求。
爲了不這些誤區,請確保在項目中始終使用庫和工具的最新版本。庫的頻繁更新還意味着你在升級時不會須要作出大量更改。大多數的庫不會在不一樣版本之間(我從你的角度來看)作出重大更改,更新起來應該至關簡單。即便你必須進行一些更改,更改中所花的時間也比確保整個項目的版本兼容性所花的時間更有效,由於項目中可能會有一個依賴項沒法升級。
使用過期工具的必然結果是最終不得不使用極新的工具。有些工具/庫仍處於測試階段或者甚至沒有一個主要版本,使用這些工具/庫就要冒着不受全部平臺支持的風險。我建議遠離這樣的庫,除非你的項目有一個很是具體的利基要求。
做爲一名開發人員,我常常忍不住直接進入代碼庫,開始從新編寫我認爲能夠改進的代碼。在處理遺留代碼時,第一步是閱讀並理解代碼,當某一部分代碼理解起來很是吃力時,你會但願重構代碼,讓其餘團隊成員避免一樣的痛苦。雖然你的隊友會欣賞這樣的行爲,但它可能會損害項目的總體狀態,由於它沒有增長任何功能價值或業務價值。正如我以前所說的,你很難向客戶證實這種作法的合理性,由於客戶寄但願於你所帶來的商業價值。在嘗試重構這樣的代碼時,也很容易誤入迷途。即便你決心對重構進行時間限制,你也可能會身不禁己,由於你不想讓本身的精力白費。
不要絕望,由於有一種方法能夠處理你不太理解的代碼。每當你渴望重構某段代碼時,請問本身如下兩個問題:
若是這兩個問題的答案都是否認的,那麼就不要對其進行重構。與代碼覆蓋同樣,只重構那些在實現過程當中要用的代碼。其餘的一切均可以添加到這個項目的「技術債務牆」。一般狀況下,所謂的「牆」外觀以下:
牆是一種方法,用來記錄代碼中的問題,或者記錄你所繼承的代碼。技術債務牆並非糟糕的設計決策的傾銷地,我認爲這是不言而喻的。它應該只應用於跟蹤現有的問題,團隊應該有意識地在項目過程當中下降技術債務。我在一些項目中的作法是:在獲得有關人員或產品全部者的批准後,優先處理迭代中的一些技術任務,以平衡所要交付的功能價值和技術價值。若是你只關注技術價值,客戶會不高興的;而若是你只關注功能價值,會不斷積累技術債務,你的代碼會愈來愈難以維護。
處理別人的代碼庫並不老是有趣或容易的,坦率地說,有時會使人沮喪。這多是因爲人們對代碼的書寫方式有不一樣的觀念,代碼的原做者能力有限,或其餘的一些因素。然而,這是大多數軟件開發人員在他們的職業生涯中必須處理的事情。
我在處理別人的代碼的實踐中積累了一些有用的作法,並嘗試着作了如上記錄。
原文連接:www.womenwhocode.com/blog/dealin…
搜索技術問答的公衆號:老齊教室
爲了方便你們閱讀、查詢本微信公衆號的資源,回覆:老齊,便可顯示本公衆號的服務目錄。