從零開始學重構——《重構,改善既有程式碼的設計》
第0篇,引言
為什麼寫這個系列
想寫這個重構系列的文章已經有一段時間了,至於寫作的動機應該有三個。
首先,是帶領的兩個團隊的所有成員都是剛畢業不久的半新人,都充滿了積極的幹勁和責任心。只是在一些基礎技能上還略有不足,或將成為他們繼續成長的瓶頸,也必然會成為團隊發展的制約。
其次,是之前在和人交流的時候,包括在面試中,也會有人提及自己重構了哪些哪些模組,但具體細問下來卻發現對重構的定義和標準有誤解,簡單地把替換為更好的實現與重構畫上了等號,意識不到重寫(rewrite)和重構(refactor)的區別。
最後,我想也是最重要的,應該是關於自我成長。在這個快速變化的時代,行業、企業與職業的界線已經越來越模糊,會發現有更多的跨界者參與到本行業的競爭中,而企業的壽命在這個快速變化的環境中也越來越短,比如:
世界500強平均壽命只有40年,1000強只有30年,而創業公司只有1-2年。
——《超級個體 2016年10月24日》
也就是說人們已經越來越難固守在一個企業和行業中憑藉混上來的資歷而保有競爭力。在這個不確定的年代,需要成長為擁有能力、特色及影響力的超級個體,才能在變化的浪潮中成為一個崛起的個人。對我自身而言,或許在積累能力的過程中,也應該擴大自身在圈子中的影響力,從而成為一個能跳脫出企業而依然保有價值的個體。
因此才有了這篇重構系列,既是為團隊和公司作出的貢獻,也是為了自身更好的成長,也希望能給有緣看到這個系列的人一定的幫助和啟發。
到底什麼是重構
到底什麼是重構?很多人對重構只有模糊的概念,知道這個專業詞彙,於是在交流中經常把重構作為重新實現了一遍
所謂重構是這樣一個過程:在不改變程式碼外在行為的前提下,對程式碼做出修改,以改程序序的內部行為。是一種經過千錘百煉形成的有條不紊的程式整理方法,可以最大程度地減少引入錯誤的機率。
——《重構——改善既有程式碼的設計》
可見,重構必須有兩個條件:一是不改變程式的行為,二是整個過程有條不紊、能夠減少錯誤。
對於第一點,意思是程式在各種輸入輸出,任何條件分支下都要有相同的行為和結果,重構前後要儘可能地完全相同。這就要求在重構過程中應當儘可能使用原有的程式碼,因為重構是一種對原有程式碼的重新組織,而不是刪除原有程式碼然後重新實現,因為在重寫的過程中很容易與原先產生不一致。不要僅僅因為原有的程式碼太過混亂就認為其沒有價值,它只是組織和結構比較混亂,但它內在的邏輯卻是正確的。(就算邏輯不正確,也應該將重構和修改分開進行,畢竟應該一次只戴一頂帽子
對於第二點,意思是整個重構的過程中是安全的,是小步前進的,而不是一種破壞性、整體性的大規模一次性的修改。我個人的體會是,在大部分時刻,如果停止修改程式碼,編譯依然能通過、程式依然能正確執行。而不是在被打斷時說:“再給我2個小時,程式才能恢復正常”。這個過程用下圖可以表示:橫座標程式碼重構的過程,縱座標程式碼程式碼整潔度,中間的標線代表程式行為的偏離度。
在重構的整個過程中,時時刻刻都與原程式的行為沒有過大的偏離,而整潔度卻會隨著重構的過程漸漸上升(不要覺得難以置信,這就是重構的力量)。而破壞性過程則不然,可能一下子因此刪除或重寫程式碼而導致很長時間內編譯無法通過,或行為不正常,在過程尾聲逐漸恢復行為,但這個新的行為很難證明與原來的保持一致。
本系列有什麼
本系列會以《重構——改善既有程式碼的設計》一書就參照,把書中大部分常用和重要的重構手法都展示、講解一遍。
每篇文章都會以一個或多個重構手法為主題來進行講解,講解時會以書中的重構步驟為基礎,結合自身的體會,並基於現實中的程式碼片斷來進行示範。手把手講述重構過程,並在文章中貼出中間過程,最後也會將文章中的程式碼及重構結果放到git專案中供大家線下實踐:https://github.com/samsai/Refactor。
重構這項技術的學習需要依靠大量的實踐和操作,”紙上得來終覺淺,絕知此事要躬行”。
在操作的過程中若有困惑也歡迎與我聯絡:[email protected],也可以主動向我提供重構的案例一起線下討論。
誰該閱讀本系列
本系統的目標讀者是那些擁有“寫出更好程式碼”夢想和目標的程式設計師。
人言:程式碼雖是給機器讀的,但終究也是給人讀的。正如同寫小說講究鳳首、豬肚和豹尾,精心程式碼也講究內聚、解耦與簡潔。一個不想當作家的程式設計師不是一個好程式設計師。如果你感覺你的程式碼像是一段剪不斷理還亂的思緒,並且想克服這種狀態,那麼請跟著我們一起習得重構這項技能。大神們早就為我們掃清了前方的道路,路一直在那裡,只是沒人走而已。
想想兩三年之後自己要成為什麼樣的人,自己和目標之間還差著什麼?重構這項技術對於你來說有什麼積極意義?
P.S. 文章中的示例和討論都涉及大量需要詳細閱讀和理解的Java程式碼,但也能遷移到其它具有OO特性的語言。