代碼重構技術探究
【引言】
最近有同事抱怨重構工作比較難做,一是溝通上存在一些問題,主要還是因為對業務邏輯不是很了解。
我們說如果在這種情況下強行進行重構的話,可能會產生很多的副作用。
要想很好的進行重構工作,必須要對業務邏輯非常清楚,對項目的整體架構也非常清楚才行。
另外一個必要條件是要有充足的測試案例,并且測試執行速度比較快,不然的話,重構的工作會受到一些延遲,進展也比較緩慢。
此外,前段時間軟件學院的劉杰珍(340654)給軟件教練們作軟件可信認證的相關介紹時,提到了目前的可信認證包括如下的內容:
設計模式,重構,面向對象設計,編程語言高階特性,其中編程語言包括C, C++, Java, Go, Python, Javascript。
針對以上內容,目前已經做了:
?span>??C語言技術特點的總結《C語言的技術特點探究》?。
接下來,我們通過這篇文章來研究分析一下代碼重構技術。
【重構解決的痛點】
1.?代碼存在太多的重復;
2.?單個函數體太大;
3.?單個代碼文件太大;
4.?模塊之間的耦合性太高;
5.?單個工程的體量過大;
以上種種問題會導致項目的后期維護和擴展非常困難。為了解決以上痛點,我們需要對現有的代碼進行重構,接下來我們先看一個例子。
【例子】
如下代碼的需求是實現玩家向四個方向的移動。
public?Position?WalkNorth() { ???var?player?=?GetPlayer(); ???player.Move("N"); ???return?player.NewPosition; } ? public?Position?WalkSouth() { ???var?player?=?GetPlayer(); ???player.Move("S"); ???return?player.NewPosition; } ? public?Position?WalkEast() { ???var?player?=?GetPlayer(); ???player.Move("E"); ???return?player.NewPosition; } ? public?Position?WalkWest() { ???var?player?=?GetPlayer(); ???player.Move("W"); ???return?player.NewPosition; }
我們發現其中的重復代碼比較多,于是我們進行了如下的重構。
public?Position?Walk(string?direction) { ???var?player?=?GetPlayer(); ???player.Move(direction); ???return?player.NewPosition; }
經過重構以后,代碼量大大減少,增強了代碼的可讀性,便于擴展和維護。
【概述】
在計算機編程和軟件設計中,代碼重構是指在不改變外部行為的情況下,對現有的計算機代碼進行重構的過程。
重構是為了改善軟件的設計、結構和實現,同時保留其現有的功能。
重構的潛在優勢包括提高代碼的可讀性和降低復雜度。
這些都可以提高源代碼的可維護性,并創建一個更簡單、更干凈或更有表現力的內部架構或對象模型,從而提高程序的可擴展性。
通常情況下,重構采用了一系列標準化的微觀重構,每一個微觀重構都是對計算機程序源代碼進行微小的修改,這些修改不改變軟件的功能需求。
許多開發環境都提供了自動化機制來執行這些基本的重構操作。
對于重構工作:
u?如果做得好,可以簡化底層邏輯,?降低復雜度,從而幫助軟件開發人員發現和修復系統中隱藏或潛伏的錯誤或漏洞。
u?如果做得不好,它可能引入新的bug,或者改變現有的功能。
【動機】
重構的動機通常是因為注意到代碼中存在了不好的“味道”。
比如,某些方法非常的長,或者是幾個函數的近似重復。
一旦意識到這類問題,可以通過重構源代碼,將其轉化為一個新的形式,去除這些壞的"味道"。
對于一個較長的函數,可以提取出多個較小的子函數。
或者對于重復的函數,可以把重復的部分放在一個共享函數里面。
這種情況下,如果不進行重構,會導致技術債的積累。而進行重構是消除技術債的方法之一。
【重構的好處】
重構活動的好處一般有兩類:
【可維護性】
可能的手段如:
l??通過將大型的函數或者組件縮減為一組單獨的、命名良好的、單一目的的函數或者組件來實現。
l??可以通過將一些方法移到一個更合適的類中。
l??或者刪除誤導性注釋來實現。
【可擴展性】
如果應用程序使用了可識別的設計模式,它會更容易擴展應用程序的功能,而且這些設計模式可能提供了一些以前不存在的靈活性。
【挑戰】
重構需要提取軟件系統結構、數據模型和應用程序內部的依賴關系,以便于獲得對現有軟件系統知識的了解。
【知識不全,?能力所限】
u?有時候,團隊的更替或者開發人員的離職,會導致對整個軟件系統的理解不充分,對于系統相關的知識可能掌握的不全面。
u?進一步的代碼重構活動需要額外的努力才能重新獲得這些知識。
u?重構活動產生的架構方面的修改可能會使軟件系統的結構體系進一步惡化。
u?惡化會影響體系結構的特性,如可維護性和可理解性,這可能導致軟件系統的完全重新開發。
【如何改善】
當使用工具和相關技術提供有關算法和代碼執行順序的數據時,代碼重構活動就有了軟件智能的保障,為軟件系統結構、數據模型和組件內部依賴關系的內部狀態提供一種可理解的格式,進而形成更高層次的抽象理解,然后對需要修改的內容和方式形成精煉的視圖。
重構的一個不可缺少的步驟就是要有充足的測試案例保證現有功能不被破壞。
【測試】
在重構之前,應該準備好充足的單元測試,以確保程序模塊仍然能像預期的那樣運行。
單元測試可以給大型的重構工作帶來穩定性。
即使是大型的重構工作,也可以通過單一的原子提交來實現。
一個常見的策略是:
u?將所有的項目代碼存儲在一個單一的存儲庫中,稱為monorepo,這可以讓安全可靠和原子化的重構跨越多個項目。
u?有了單元測試之后,重構就是一個迭代的循環,即先做一個小的程序變換,然后測試確保正確性,然后再做另一個小的程序變換。
u?如果在任何一點上測試失敗了,最后的小的改動就會被撤銷,并以不同的方式再重復進行。
u?通過上面這些許多小的步驟,程序就從原來的狀態到了你希望的狀態。
u?為了使這個過程更加實用高效,單元測試必須運行得非常快,不然的話程序員們要花很大一部分時間等待測試結束。
u?極限編程和其他敏捷軟件開發的擁護者將這項活動描述為軟件開發周期中不可分割的一部分。
【相關技術】
以下是一些微重構的例子,其中一些可能只適用于某些語言。許多開發環境為這些微重構提供了自動支持。
例如,程序員可以點擊一個變量的名稱,然后在上下文菜單中選擇?"封裝字段"進行重構。
然后IDE會提示額外的細節,通常會有合理的默認值和代碼修改的預覽。
在程序員確認后,它將在整個代碼中執行所需的更改。
u?有助于更多理解程序結構的技術
n??程序依賴關系圖--數據和控制依賴關系的顯式表示
n??系統依賴圖--PDG之間過程調用的表示方式
n??軟件智能----逆向工程的初始狀態,以了解現有的應用內的依賴關系。
u?可實現更多抽象化的技術
n??封裝字段--用getter和setter方法
n??通用化類型----創建更多的通用類型,讓更多的代碼共享。
n??將類型檢查代碼改為狀態/戰略代碼
n??用多態性取代條件性
u?將代碼分解成更多邏輯碎片的技巧
n??組件化將代碼分解成可重用的語義單元,這些語義單元呈現出清晰的、定義明確的、簡單易用的接口。
n??提取類,將現有類中的部分代碼移動到一個新的類中。
n??提取方法,將一個較大的方法的一部分提取變成一個新的方法。通過將代碼分解成更小的部分,提高代碼的可讀性。
u?改進代碼名稱和位置的技巧
n??移動方法或移動字段--移動到更合適的類或源文件中
n??重命名方法或重命名字段----將名稱改成一個新的、能更好地揭示其用途的名稱
n??拉升----在面向對象編程(OOP)中,移到超類中去
n??下推--在OOP中,移動到子類
u?自動克隆檢測
【硬件重構】
雖然重構這個術語最初只指軟件代碼的重構,但近年來,用硬件描述語言(HDL)編寫的代碼也正在被重構。
硬件重構這個術語被用作硬件描述語言中代碼重構的速記術語。
由于HDLs不被大多數硬件工程師認為是編程語言,所以硬件重構被視為一個獨立于傳統代碼重構的領域。
Zeng和Huss提出了模擬硬件描述的自動重構,在他們的方法中,重構保留了硬件設計的模擬行為。其改進的非功能測量是重構后的代碼可以被標準的合成工具處理,而原始代碼則不能。
Synopsys的研究員Mike Keating也對數字HDL的重構(盡管是手工的重構)進行了研究,他的目標是使復雜的系統更容易理解,從而提高設計者的工作效率。
【自動代碼重構】
許多軟件編輯器和IDE都有自動重構支持。
它們既可以重構應用程序代碼,也可以重構測試代碼,以下是其中幾個例子:
u?DMS軟件重構工具包(支持C、C++、C#、COBOL、Java、PHP等語言的大規模重構)
u?基于Eclipse:
n??Eclipse(適用于Java,并在較小程度上適用于C++、PHP、Ruby和JavaScript。)
n??PyDev (適用于Python)
n??Photran (Eclipse IDE的Fortran插件)
u?Embarcadero Delphi
u?基于IntelliJ的:
n??AppCode (用于Objective-C、C和C++)
n??IntelliJ IDEA (用于Java)
n??PyCharm (用于Python)
n??WebStorm (用于?JavaScript)
n??Android Studio (適用于Java)
u?JDeveloper (適用于Java)
u?NetBeans (適用于Java)
u?Smalltalk
u?基于Visual Studio的:
n??Visual Studio (適用于.NET和C++)
n??CodeRush (Visual Studio的附加組件)
n??Visual Assist (Visual Studio的插件,支持C#和C++的重構)
u?Wing IDE (適用于Python)
u?Xcode(適用于C、Objective-C和Swift)
u?Qt Creator(適用于C++、Objective-C和QML)
【小結】
本文對代碼重構技術的概念,動機,好處,挑戰和技術方法進行了學習和探討,希望對大家有幫助。
歡迎討論。
架構設計
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。