我們一直在尋找各種方法來清理代碼、降低復雜性和改善功能。而重構為我們指明了前進的方向。
1、什么是重構?
Martin Fowler曾出版了兩本有關重構的書籍,他認為:
重構指的是,在不改變代碼的外部行為,只改善其內部結構的方式下,修改軟件系統的過程。重構是一種有條理的清理代碼的方式,可以最大程度地減少引入bug的機會。本質上,重構意味着在代碼編寫完成后,改進代碼的設計。
2、重構有什么好處?
重構源代碼有數不清的好處。首先,重構可以將混亂、不正確和/或重復的代碼轉換成整潔的代碼。它可以解決多位開發人員協同工作時可能引發的代碼標准化問題。重構可以提高可讀性,改善源代碼的可維護性以及整體結構和功能。重構可以使代碼更易於擴展和添加新功能。刪除不必要的代碼(比如重復代碼)可以減少代碼所使用的內存,並加快執行速度。
例如,在2014年,Kickstarter的工程師面臨着一個巨大的挑戰:由於用戶數量呈指迅速增長,導致查詢性能下降。為此,他們將MySQL查詢重構為Redis,減少了100毫秒的加載時間,從而減少了加載時間的差異並提高了網站的整體速度。
3、技術負債與重構
簡而言之,重構是消除或減少技術負債的一種方式。
重構對於長期維持的代碼質量、安全性和性能至關重要。如果沒有定期的重構,開發人員就會承受巨大的技術負債。重構代碼的機會越少,技術負債就會越多,開發新功能也會變得越來越難。
4、重構的指標
我們可以通過各種指標,衡量重構代碼的優先級。在指標的幫助下,我們可以有條不紊地計划重構,每一次都專心完成最重要的任務。
此外,你需要通過指標來衡量重構的效果。我們不僅需要重構低效的代碼,而且還可以通過修改低效代碼增加價值。為了獲得真正的價值,你需要進行測試,包括單元測試和功能測試。除此之外,還有一些其他方面的指標,比如發現的bug數減少,以及降低循環復雜性(重構的目標是降低復雜性)。高度復雜的方法或功能(比如超過350行的方法或功能)就是良好的重構對象。
此外,我們還需要考慮,如何將重構融合到更廣泛的團隊目標或有關工作流和任務的里程碑中。
5、代碼重構示例
代碼重構的示例非常多,為了簡潔起見,我們介紹以下幾種:
紅色,綠色和重構
重構與單元測試息息相關。最常見的形式之一就是敏捷方法固有的測試驅動開發(Test-Driven Development,即TDD)。你可以在編寫代碼之前先編寫測試。從本質上來說,應該由測試來驅動程序,說明代碼應該執行的操作。
紅色,綠色和重構是測試驅動開發的一個示例:
- 紅色:編寫沒有實現代碼的測試套件,必然會失敗。
- 綠色:編寫實現代碼,剛剛好可以通過測試套件。
- 重構:尋找優化和改進代碼的方法。
提取方法(又名提取函數)
將代碼片段從現有方法移到新方法中,而新方法的名稱明確說明了其功能。這種技術有助於降低復雜性並提高代碼的可讀性。
提取變量
如果遇到難以理解的表達式,或者該表達式在整個代碼中重復了多次,則可以通過提取變量重構,將表達式或其中一部分放入一個復雜度較低且更易於理解的變量中。這樣可以減少復雜性和代碼重復。
按抽象建立分支
按抽象建立分支可以逐步對軟件系統進行大規模地修改,而你則可以一邊修改代碼,一邊定期發布系統。這種方法可以降低在分支上重構代碼的復雜性,避免在合並代碼時出現問題。
方法組合
代碼過長不便於理解,而且也不方便修改。方法組合指的是一系列的操作,將方法改成順序結構並刪除重復的代碼。這些操作包括內聯方法、內聯模板、用查詢代替模板、拆分臨時變量以及刪除對參數的賦值等。
6、重構代碼的工具
你需要專業的重構工具嗎?Martin Fowler表示,自動化的工具有幫助但不是必需的。他指出:
“許多語言都有IDE,可以自動執行許多常見的重構。這些是非常有價值的工具,可以幫助我更快地重構代碼。但是,這些工具不是必不可少的,我經常在沒有工具支持的情況下編寫程序,每次只邁出一小步,並通過頻繁的測試來發現錯誤。”
許多開發環境都可以自動化重構,一些常見的重構工具包括:
- Visual studio intellicode
- Eclipse IDE
- Spring Tool Suite 4
- Rider
- IntelliJ IDEA
- SonarQube
7、重構與工程經理的難題
為了解決引發重構需求的問題,首先我們需要弄清楚公司的運營方式。在着手重構之前,請先回答下列幾個問題:
- 哪些任務最優先?
- 開發的速度如何?
- 開發人員是否感覺到了快速交付代碼的壓力?
- 解決技術負債的流程都有哪些?
- 實施了哪些類型的代碼審核?
- 團隊成員是否具備適當的重構技能?
- 公司的文檔標准是什么?
如果不解決引發重構需求的根本問題,那么問題只會愈演愈糟。
8、高級管理層對重構的支持
你們公司可能並沒有在基礎設施和維護上投入太多資金。
可能會有人說,應該將花費在重構上的時間投入到新功能開發上。
但是,我們仍然應該看一看重構的好處,以及它們與工作流程、客戶、收入和業務增長的關系。重構得當可以改善代碼,交付有效更新以及急需的功能,從而吸引新客戶和回頭客。即使在成功發布產品之后,軟件公司也可以通過這種方式保持競爭力。
為了獲取高層管理的支持,還有一個更好的方法,即量化團隊當前花費在修復原始代碼中的錯誤或bug上的時間。具體一點,比如每天一個小時?每天兩個小時?持續記錄一個星期,你就會驚訝地發現原來團隊每年需要花費數周或數月時間來修復遺留的代碼。
9、團隊支持與重構:一個Sprint還是馬拉松?
很難在團隊內部開展重構工作?提及重構就會哀聲載道?順利開展重構的最重要的標志就是有計划、有目標以及有文檔記錄的行動。Ron Jeffries(極限編程的三大創始人之一)將重構比喻為清道:
“花些時間清出一條道來,那么下一次我們就可以直奔我們要構建的下一個功能,而無需繞過雜草和灌木叢。”
但是,他強調指出,糟糕的代碼需要花費很長的時間來清理,而且重構應該經過深思熟慮:
“如果我們只改進手頭的代碼,而忽略目前不涉及的代碼,那么以后必然會走回頭路。”
在同一個Sprint中,我們經常發現后面的功能用到了我們之前清理過的代碼。我們就會立即享受重構的好處。如果我們等積攢了一堆技術負債,再開始重構,那么我們享受的好處會延遲,甚至可能會在一些沒大有用的地方浪費精力。
產品工程師兼首席技術官Andreas Klinger是Fix-it Friday的粉絲,他表示:
“Fix-it Friday的規則很簡單:除非當前的項目十萬火急,否則周五的工作就應該是重構。讓工程師選擇他們的工作。我們不應該因為微觀管理而抹殺這種樂趣。有些人會嘗試新的庫。有些人會修復積壓的bug。這兩種工作都很好。我們嘗試鼓勵大家平衡這些任務。”
無論采用哪種方法,你都需要慎重思考,詢問團隊哪些代碼最影響他們的效率。
- 修復哪些代碼對你的其他代碼產生的影響最大?
- 解決哪些問題得到的回報最多?
你不太可能找到一整塊專門的時間來重構代碼,重構代碼必然會犧牲你花費在其他項目上的時間,但請不要低估定期堅持開展小范圍的重構帶來的影響。聚沙成塔,集腋成裘,最終你會獲得豐厚的回報。
10、文檔與重構
標准化命名約定之類的文檔可以讓每個人都達成共識。Xerox的高級開發人員的研究發現,缺乏文檔是重構最大的難題之一。
記錄重構的工作內容不僅可以記錄花費的時間,而且還可以為將來的團隊成員提供說明。
最后,你還通過文檔記錄下自己的成功:重構帶來的最大成功是什么?這些可以成為代碼審核的考慮因素嗎?
作者 | Alex Omeyer
譯者 | 彎月
出品 | CSDN(ID:CSDNnews)
原文鏈接:https://medium.com/swlh/the-ultimate-engineers-guide-to-code-refactoring-c38372632906
近期熱文推薦:
1.1,000+ 道 Java面試題及答案整理(2021最新版)
2.終於靠開源項目弄到 IntelliJ IDEA 激活碼了,真香!
3.阿里 Mock 工具正式開源,干掉市面上所有 Mock 工具!
4.Spring Cloud 2020.0.0 正式發布,全新顛覆性版本!
覺得不錯,別忘了隨手點贊+轉發哦!