大約是工作三年后,職業(yè)倦怠毫無征兆的襲擊了我,我莫名的感到:這一輩子就這樣了,每天的工作就是寫相同的代碼,要命的是,自己在一個領(lǐng)域越精通,別人就越希望自己寫同樣的模塊——再快一點(diǎn)。使我渡過這段時光的,是一些編程行業(yè)的老書,對于一個原本追求時髦技術(shù)的程序員來說,這樣的反轉(zhuǎn)令自己也很驚訝,其中就有這本《重構(gòu)》,多年后,再次捧讀,希望自己如《黑客帝國》里的neo,回到源碼,去理解為何重構(gòu)即不是傳說中的銀彈,卻又如此重要。本篇為第一部分,先來說說看待重構(gòu)的三心。

拋掉對重構(gòu)的敬畏之心
1. 重構(gòu)給出了具體的操作方法。
重構(gòu)不是建立在空中的構(gòu)建思想,而是從實(shí)踐中歸納出來的操作手冊。比如書中提到的要點(diǎn)之一:
事不過三,三要重構(gòu)。
這條規(guī)則給出了重構(gòu)時機(jī)的具體判斷方法:一個值,一段代碼,相同的功能,如果重復(fù)出現(xiàn)了 兩次以上,就要提取為宏,變量,方法,或模塊,以方便重用。這不是建議,從代碼質(zhì)量來說,這是要求,也是開發(fā)者從小工到專家的必由之路,事實(shí)上,除此之外,我不知道還有別的編寫代碼的方法。
2. 重構(gòu)早已在開發(fā)者身邊。
幾乎所有開發(fā)工具(Eclipse、Xcode...)都內(nèi)置重構(gòu)工具,他們的使用與代碼編輯器一樣簡單。
如果你是一名iOS開發(fā)者,請參閱Xcode8 五分鐘重構(gòu)起步
要對重構(gòu)有耐心
由于重構(gòu)不改變程序的外在表現(xiàn),換而言之,即沒有加入任何新功能,因此項(xiàng)目經(jīng)理和老板不會主動要求開發(fā)者重構(gòu),甚至開發(fā)者提出時,會招來反對:這個項(xiàng)目還剩一個星期,還有N個需求未實(shí)現(xiàn),現(xiàn)在你請求花費(fèi)兩天時間,什么都不做。開發(fā)者幾乎都承擔(dān)不了這樣的壓力,但是,比延誤工期更嚴(yán)重的是,一個臃腫的,不易修改的項(xiàng)目,最終將面臨添加需求困難,運(yùn)行效率低下,以致達(dá)不到可用的性能,項(xiàng)目被砍掉,失敗幾乎不可避免。
那么作為開發(fā)者,應(yīng)該怎么處理這個矛盾呢?一個可行的方法是,把重構(gòu)當(dāng)做開發(fā)的一部分,一邊開發(fā)一邊重構(gòu),先快速的堆疊代碼,實(shí)現(xiàn)功能,然后在功能不變的基礎(chǔ)上(寫好單元測試),逐步重構(gòu)。

對于吹噓重構(gòu)有戒心
不要對別人吹噓重構(gòu)
重構(gòu)是一系列技法,就如一個優(yōu)秀木匠不會吹噓自己的刀法一樣,他表現(xiàn)自己的,永遠(yuǎn)是作品,開發(fā)者的作品就是程序,可擴(kuò)展,少改動,高效,穩(wěn)健的程序,如果團(tuán)隊(duì)里有人說:我現(xiàn)在不重構(gòu)就沒法寫代碼。大概他就真的只是不會寫代碼而已。
本人面試過一些剛畢業(yè)的開發(fā)者,在最后的提問環(huán)節(jié),他提出的問題是:你們用什么開發(fā)環(huán)境?接著他還進(jìn)一步強(qiáng)調(diào)自己一定要使用**Source Insight
**(一種Windows平臺流行的開發(fā)集成環(huán)境,基于代碼語義管理代碼),否則就無法寫代碼。當(dāng)時我有點(diǎn)錯愕,面對了解公司環(huán)境的寶貴機(jī)會,不問福利待遇,不問升職通道,卻糾結(jié)一個開發(fā)工具。后來我發(fā)現(xiàn),很多初學(xué)者(也包括我自己)對工具有種癡迷,這當(dāng)然也不是壞事,但對自己用的開發(fā)工具夸夸其談,只能說明開發(fā)者的眼界不夠開闊,水平有局限。

當(dāng)聽到有人將重構(gòu)奉為靈丹妙藥,要格外小心,對此保持警惕。
有的技術(shù)領(lǐng)導(dǎo)人,動不動就說“下面我們進(jìn)入重構(gòu)階段了”,仔細(xì)觀察發(fā)現(xiàn):每每他提出的時機(jī),都是項(xiàng)目無法按時完成,某些功能實(shí)現(xiàn)不了時,公司領(lǐng)導(dǎo)還無法反駁,懂點(diǎn)技術(shù)的都明白重構(gòu)的重要性。

那么,如何鑒別這種拿重構(gòu)“忽悠”的行為呢?可以從以下幾點(diǎn):
- 檢查要進(jìn)入重構(gòu)階段的團(tuán)隊(duì)有沒有寫好對應(yīng)的單元測試,這些測試是否自動測試。
- 是否為重構(gòu)的項(xiàng)目新開版本管理庫,如果是,那這不是重構(gòu),而是 重寫。
- 最終確認(rèn)最開始要求添加的需求是否被完成。
最后這點(diǎn)看起來有點(diǎn)二,但實(shí)際中常常發(fā)生,團(tuán)隊(duì)說,我開始重構(gòu)啦,于是在大汗淋漓的兩周后,團(tuán)隊(duì)只能保證“重構(gòu)”后的項(xiàng)目勉強(qiáng)運(yùn)行,項(xiàng)目進(jìn)入了新階段——bug修復(fù),然后就再也沒人提最初提出的新功能新需求了。

對于第一點(diǎn),我們要理解重構(gòu)的目標(biāo)是
不改變代碼外在行為的前提下,對代碼進(jìn)行修改,以改進(jìn)程序的內(nèi)部結(jié)構(gòu)。
如何保證代碼外在行為沒有改變?就得靠單元測試了,這里將單元測試作為代碼或重構(gòu)的質(zhì)量標(biāo)準(zhǔn),誰也不想一個正在運(yùn)行的程序,被修改后引入一堆Bug。
既然重構(gòu)講究的是小步修改,每次改完后都要通過單元測試,那么第二點(diǎn)也很好理解了,重建版本庫則意味著大段地搬移代碼,這個過程很難保證代碼質(zhì)量,得到的很可能是 未經(jīng)驗(yàn)證 的代碼。
既然重構(gòu)是一種編程手法,那么實(shí)踐中的重構(gòu)是如何操作的?該如何避免重寫而**優(yōu)雅地重構(gòu)呢?
下篇將通過一個具體的例子,體會重構(gòu)的過程,請關(guān)注我的簡書。