代碼重構終極指南

作者 | Alex Omeyer

譯者 | 彎月

出品 | CSDN(ID:CSDNnews)

我們一直在尋找各種方法來清理代碼、降低複雜性和改善功能。而重構爲我們指明瞭前進的方向。

本文涵蓋的主題如下:

01

Martin Fowler 曾出版了兩本有關重構的書籍,他認爲:

重構指的是,在不改變代碼的外部行爲,只改善其內部結構的方式下,修改軟件系統的過程。重構是一種有條理的清理代碼的方式,可以最大程度地減少引入 bug 的機會。本質上,重構意味着在代碼編寫完成後,改進代碼的設計。

02

重構源代碼有數不清的好處。首先,重構可以將混亂、不正確和 / 或重複的代碼轉換成整潔的代碼。它可以解決多位開發人員協同工作時可能引發的代碼標準化問題。重構可以提高可讀性,改善源代碼的可維護性以及整體結構和功能。重構可以使代碼更易於擴展和添加新功能。刪除不必要的代碼(比如重複代碼)可以減少代碼所使用的內存,並加快執行速度。 

例如,在 2014 年,Kickstarter 的工程師面臨着一個巨大的挑戰:由於用戶數量呈指迅速增長,導致查詢性能下降。爲此,他們將 MySQL 查詢重構爲 Redis,減少了 100 毫秒的加載時間,從而減少了加載時間的差異並提高了網站的整體速度。

03

簡而言之,重構是消除或減少技術負債的一種方式。

重構對於長期維持的代碼質量、安全性和性能至關重要。如果沒有定期的重構,開發人員就會承受巨大的技術負債。重構代碼的機會越少,技術負債就會越多,開發新功能也會變得越來越難。

04

我們可以通過各種指標,衡量重構代碼的優先級。在指標的幫助下,我們可以有條不紊地計劃重構,每一次都專心完成最重要的任務。

此外,你需要通過指標來衡量重構的效果。我們不僅需要重構低效的代碼,而且還可以通過修改低效代碼增加價值。爲了獲得真正的價值,你需要進行測試,包括單元測試和功能測試。除此之外,還有一些其他方面的指標,比如發現的 bug 數減少,以及降低循環複雜性(重構的目標是降低複雜性)。高度複雜的方法或功能(比如超過 350 行的方法或功能)就是良好的重構對象。

此外,我們還需要考慮,如何將重構融合到更廣泛的團隊目標或有關工作流和任務的里程碑中。

05

代碼重構的示例非常多,爲了簡潔起見,我們介紹以下幾種:

紅色,綠色和重構

重構與單元測試息息相關。最常見的形式之一就是敏捷方法固有的測試驅動開發(Test-Driven Development,即 TDD)。你可以在編寫代碼之前先編寫測試。從本質上來說,應該由測試來驅動程序,說明代碼應該執行的操作。

紅色,綠色和重構是測試驅動開發的一個示例:

提取方法(又名提取函數)

將代碼片段從現有方法移到新方法中,而新方法的名稱明確說明了其功能。這種技術有助於降低複雜性並提高代碼的可讀性。

提取變量

如果遇到難以理解的表達式,或者該表達式在整個代碼中重複了多次,則可以通過提取變量重構,將表達式或其中一部分放入一個複雜度較低且更易於理解的變量中。這樣可以減少複雜性和代碼重複。

按抽象建立分支

按抽象建立分支可以逐步對軟件系統進行大規模地修改,而你則可以一邊修改代碼,一邊定期發佈系統。這種方法可以降低在分支上重構代碼的複雜性,避免在合併代碼時出現問題。

方法組合

代碼過長不便於理解,而且也不方便修改。方法組合指的是一系列的操作,將方法改成順序結構並刪除重複的代碼。這些操作包括內聯方法、內聯模板、用查詢代替模板、拆分臨時變量以及刪除對參數的賦值等。

06

你需要專業的重構工具嗎?Martin Fowler 表示,自動化的工具有幫助但不是必需的。他指出:

“許多語言都有 IDE,可以自動執行許多常見的重構。這些是非常有價值的工具,可以幫助我更快地重構代碼。但是,這些工具不是必不可少的,我經常在沒有工具支持的情況下編寫程序,每次只邁出一小步,並通過頻繁的測試來發現錯誤。”

許多開發環境都可以自動化重構,一些常見的重構工具包括:

07

爲了解決引發重構需求的問題,首先我們需要弄清楚公司的運營方式。在着手重構之前,請先回答下列幾個問題:

如果不解決引發重構需求的根本問題,那麼問題只會愈演愈糟。

08

你們公司可能並沒有在基礎設施和維護上投入太多資金。

可能會有人說,應該將花費在重構上的時間投入到新功能開發上。

但是,我們仍然應該看一看重構的好處,以及它們與工作流程、客戶、收入和業務增長的關係。重構得當可以改善代碼,交付有效更新以及急需的功能,從而吸引新客戶和回頭客。即使在成功發佈產品之後,軟件公司也可以通過這種方式保持競爭力。 

爲了獲取高層管理的支持,還有一個更好的方法,即量化團隊當前花費在修復原始代碼中的錯誤或 bug 上的時間。具體一點,比如每天一個小時?每天兩個小時?持續記錄一個星期,你就會驚訝地發現原來團隊每年需要花費數週或數月時間來修復遺留的代碼。

09

很難在團隊內部開展重構工作?提及重構就會哀聲載道?順利開展重構的最重要的標誌就是有計劃、有目標以及有文檔記錄的行動。Ron Jeffries(極限編程的三大創始人之一)將重構比喻爲清道:

“花些時間清出一條道來,那麼下一次我們就可以直奔我們要構建的下一個功能,而無需繞過雜草和灌木叢。”

但是,他強調指出,糟糕的代碼需要花費很長的時間來清理,而且重構應該經過深思熟慮:

“如果我們只改進手頭的代碼,而忽略目前不涉及的代碼,那麼以後必然會走回頭路。”

在同一個 Sprint 中,我們經常發現後面的功能用到了我們之前清理過的代碼。我們就會立即享受重構的好處。如果我們等積攢了一堆技術負債,再開始重構,那麼我們享受的好處會延遲,甚至可能會在一些沒大有用的地方浪費精力。

產品工程師兼首席技術官 Andreas Klinger 是 Fix-it Friday 的粉絲,他表示:

“Fix-it Friday 的規則很簡單:除非當前的項目十萬火急,否則週五的工作就應該是重構。讓工程師選擇他們的工作。我們不應該因爲微觀管理而抹殺這種樂趣。有些人會嘗試新的庫。有些人會修復積壓的 bug。這兩種工作都很好。我們嘗試鼓勵大家平衡這些任務。”

無論採用哪種方法,你都需要慎重思考,詢問團隊哪些代碼最影響他們的效率。

你不太可能找到一整塊專門的時間來重構代碼,重構代碼必然會犧牲你花費在其他項目上的時間,但請不要低估定期堅持開展小範圍的重構帶來的影響。聚沙成塔,集腋成裘,最終你會獲得豐厚的回報。

10

標準化命名約定之類的文檔可以讓每個人都達成共識。Xerox 的高級開發人員的研究發現,缺乏文檔是重構最大的難題之一。

記錄重構的工作內容不僅可以記錄花費的時間,而且還可以爲將來的團隊成員提供說明。

最後,你還通過文檔記錄下自己的成功:重構帶來的最大成功是什麼?這些可以成爲代碼審覈的考慮因素嗎?

原文鏈接:https://medium.com/swlh/the-ultimate-engineers-guide-to-code-refactoring-c38372632906

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/Lw3M8gAKq9wiBjT-tPfHZQ