讀書感想--Refactoring 重構(gòu)

對于需要實際編寫代碼的開發(fā)人員,最好把這本書常備在手邊用作工具書。


作為學(xué)習(xí)成長中的軟件開發(fā)者,重構(gòu)總是帶著一點高深莫測。一方面,如果有人說“我在對某模塊進行重構(gòu)”,瞬間就有了高大上的感覺;而一旦出現(xiàn)問題,“重構(gòu)”就成了把萬能鑰匙,幾乎所有的問題都可以用“重構(gòu)一下”來解決。

然而這只是種錯覺。

如何重構(gòu)是比較簡單的,真正重要的,是決定在什么時候、針對哪些代碼、做到什么程度的重構(gòu),以及何時停止。就好比作為士兵沖鋒陷陣,和作為將軍指揮千軍萬馬,難度差別不言而喻(假如不考慮陣亡的危險性的話)。


目的

對于真正的工程來說,首先應(yīng)該明確重構(gòu)的目的。業(yè)務(wù)分離,易于維護和擴展,增強可靠性,提升性能,明確業(yè)務(wù)邏輯,這些都是常見的重構(gòu)理由。為了重構(gòu)而重構(gòu)是不可取的;過度設(shè)計和炫技同樣是不好的理由。工程師可以有藝術(shù)家的氣質(zhì),但是工程不能做成藝術(shù)品。


范圍

明確目的后,應(yīng)該首先判斷重構(gòu)的層次。很多時候,重構(gòu)并不能直接涉及到代碼的變更,比如服務(wù)的重組、服務(wù)器的壓力分離、數(shù)據(jù)庫的主從備份,廣義來講都屬于重構(gòu),也超出了這本書的范圍。本書適用于代碼層的重構(gòu)。


時機

重構(gòu)的時機及范圍也很重要。書中提到:“如果你需要給一個運行中的系統(tǒng)添加功能,你不可能說服經(jīng)理把系統(tǒng)停止運行兩個月讓你進行重構(gòu)。你只能一點一點地做你的工作,今天一點點,明天一點點?!薄皯?yīng)該根據(jù)需求安排自己的工作,只在需要添加新功能或修補錯誤時才進行重構(gòu)。你不必一開始就完成整個系統(tǒng)的重構(gòu),重構(gòu)程度只要能滿足其它任務(wù)的需要就行了。反正明天你還可以回來重構(gòu)?!薄罢麄€團隊都必須意識到:有一個大型重構(gòu)正在進行,每個人都應(yīng)該相應(yīng)地安排自己的行動?!?/p>

這些不僅僅是技術(shù)問題,涉及到了商業(yè)、人事、項目管理甚至名聲不怎么好的“辦公室政治”,都需要在重構(gòu)前搞定。


是否需要重構(gòu)

是否需要重構(gòu)也值得仔細探討:重構(gòu)一定會對當(dāng)前的工作產(chǎn)出造成影響,如果處理不當(dāng)還會引入新的問題;但是“長遠”來看是好的。

問題就出現(xiàn)這個不確定的“長遠”上:有可能項目根本不需要“長遠”,比如廣告活動用的一次性的小軟件;有可能犧牲了當(dāng)下的功能性產(chǎn)出,就會被競爭對手搶占市場,從而也就沒有“長遠”;或者當(dāng)“長遠”的好處出現(xiàn)時,當(dāng)前開發(fā)人員已經(jīng)不在此崗位上了。

另外還有一個好處:重構(gòu)可以幫助開發(fā)人員了解代碼,對于接手其它人的代碼是很有用的??墒怯泻芏鄷r候,開發(fā)人員會放棄重構(gòu),重新造一個輪子出來??赡苁墙邮值碾y度太大還不如重寫,也可能只是“文人相輕”(這并不罕見。我曾經(jīng)見到過公司里每新增一個項目就要招聘一個新開發(fā)經(jīng)理,幾年下來,公司里各種項目沒有技術(shù)相同的,C++,Java,QT,Python,PHP,NodeJS,AngularJS,React……當(dāng)然這些并不是同一層次上的技術(shù),不過也已經(jīng)足夠眼花繚亂了)。


重構(gòu)的局限

在真正重構(gòu)前,還需要考慮到重構(gòu)的局限。重構(gòu)并不是銀彈。很多時候我們是為了提升性能而進行重構(gòu),但是重構(gòu)本身往往會降低一定的效率,因為多數(shù)的重構(gòu)手法都會引入新的類、函數(shù)調(diào)用和繼承關(guān)系等。但是重構(gòu)可以使結(jié)構(gòu)和邏輯更加清晰,從而暴露出真正的瓶頸,如實現(xiàn)策略、功能劃分等,進而著手加以改進。而新引入的這部分內(nèi)容,對性能的影響微乎其微,現(xiàn)在的編譯器也基本上都會將其優(yōu)化。


本書內(nèi)容

這本書是非常細節(jié)的重構(gòu),細到了命名、參數(shù)、函數(shù)/方法等程度。對于剛剛接觸重構(gòu)的開發(fā)人員,直接看下去,很容易陷入小型重構(gòu)的局限而失去視野。

因此建議先快速通讀一遍,對于每一個重構(gòu)手法著重理解概念、目的和場景即可,代碼示例可以先略過。

第二次再仔細研讀每一個例子。本書不僅適用于重構(gòu),對于提高代碼質(zhì)量也很有幫助。

后續(xù)就當(dāng)作工具書,需要時翻一翻。類似于GoF的《設(shè)計模式》和算法類書籍。

另外本書是針對面向?qū)ο笳Z言的重構(gòu);對于現(xiàn)在流行的函數(shù)式編程有借鑒意義,需要按照具體情況調(diào)整。

本書并不是可以直接套用的普適規(guī)則,需要根據(jù)具體情況分析。書中很多重構(gòu)是介紹了兩個方向的實現(xiàn)方法:從A重構(gòu)到B,再從B重構(gòu)到A。具體如何實施需要由開發(fā)人員定奪。

每一種重構(gòu)手法,作者都給出了具體的操作步驟,可實踐性很強。


準備知識

熟悉設(shè)計模式會有很大幫助。GOF的《設(shè)計模式》不用多說,如果不太容易理解也可以讀Head First系列的設(shè)計模式。

需要熟悉一種面向?qū)ο笳Z言,最好是Java,因為書中的例子都是使用Java的。C++的要更加復(fù)雜(書中有提到),因為C++并不是完全面向?qū)ο蟮摹?/p>

了解自動化測試、測試驅(qū)動開發(fā)等內(nèi)容,尤其是測試的重要性,能夠更好理解書中的重構(gòu)步驟。


大型重構(gòu)

在書的后部,作者提到了幾種大型重構(gòu):Tease Apart Inheritance(梳理并分解繼承體系),Convert Procedural Design to Objects(將過程化設(shè)計轉(zhuǎn)化為對象設(shè)計),Separate Domain from Presentation(將領(lǐng)域和表述/顯示分離),Extract Hierarchy(提煉繼承體系)。

這些是層次較高的重構(gòu),需要綜合運用前面提到的單一手法。


重構(gòu)的準備工作

重構(gòu)需要工具支持,否則成本會非常高(主要是時間成本)?,F(xiàn)代的IDE多數(shù)已經(jīng)支持了重構(gòu)的一些基本功能,比如重命名,抽取變量,抽取函數(shù)等。

要能夠撤銷重構(gòu),返回到重構(gòu)前的狀態(tài)。主要是用于重構(gòu)失敗的回滾,因此svn、git等代碼版本控制工具是必要的。

重構(gòu)時不要修改代碼,僅保證所有舊功能不變,這是需要堅持的原則。


總結(jié)

想要提升技能水平,這本書可以算作必讀書目之一。然而重構(gòu)不是空談,需要長時間的經(jīng)驗積累。本書提供了很多手法,但是如同作者自己所說,只是一個起步。

路還很長。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容