代碼重構(gòu)閱讀心得[轉(zhuǎn)]
  最近閱讀Martin Flower的《重構(gòu)》,對(duì)自己有許多啟發(fā),以前認(rèn)為一些正確的觀點(diǎn)現(xiàn)在看來(lái)也不那么正確了;同時(shí)發(fā)現(xiàn)對(duì)重構(gòu)的理解只有在閱讀了書(shū)之后更加徹底;在閱讀《重構(gòu)》之后我對(duì)其中幾點(diǎn)有點(diǎn)感觸:

 

  1. 在沒(méi)有具體閱讀《重構(gòu)》之前,我認(rèn)為重構(gòu)就是將代碼變的容易理解,容易維護(hù),但在閱讀了《重構(gòu)》之后才發(fā)現(xiàn)重構(gòu)不僅可以利用到重新構(gòu)造已有的代碼,也可以幫助我們?cè)陂喿x代碼的過(guò)程中增加我們的對(duì)代碼理解的速度。其實(shí)我想每個(gè)學(xué)習(xí)編寫代碼的同行都在學(xué)習(xí)的過(guò)程中閱讀過(guò)別人的代碼,然后還有可能將別人的代碼拿到計(jì)算機(jī)上編譯運(yùn)行來(lái)查看結(jié)果表現(xiàn)。實(shí)際上我認(rèn)為這在某種意義上屬于重構(gòu),只是重構(gòu)的粒度有多大,或許你修改別人的代碼一部分來(lái)查看修改的結(jié)果,從而幫助自己掌握軟件中的更多特性,或者說(shuō)讓自己修改的代碼表現(xiàn)出原來(lái)的功能。Martin Flower說(shuō)的就是如此,我們?nèi)绻麤](méi)有得到別人完整的文檔,那我們?cè)趺礃硬拍芾斫鈩e人的代碼來(lái),好的辦法就是我們一邊閱讀別人的代碼,一邊部分部分的修改他人的代碼,然后測(cè)試每次修改的結(jié)果與以前的結(jié)果是否一樣,如果一樣,那么你的重構(gòu)代碼是正確,那么你肯定能夠理解你自己寫的代碼吧(自己都不理解自己的代碼就不要干了);別人的代碼就這樣在我們一部分一部分重構(gòu)當(dāng)中被我們理解了。

 

  2. 以前我們寫代碼的時(shí)候喜歡設(shè)計(jì),設(shè)計(jì)的我們認(rèn)為很詳細(xì)了,然后開(kāi)始將所有的功能模塊都寫完,接著再調(diào)試,在調(diào)試的過(guò)程中我們可能花費(fèi)比寫代碼長(zhǎng)的多的時(shí)間。是的,因?yàn)槟阍谶\(yùn)行一個(gè)復(fù)雜的東西,當(dāng)然不容易搞定了。Martin Flower認(rèn)為我們調(diào)試的時(shí)間可以不用那么長(zhǎng),原因是我們不能在寫完了一個(gè)復(fù)雜系統(tǒng)的時(shí)候再調(diào)試,我們可以先建立一個(gè)好的測(cè)試用例,在寫這個(gè)測(cè)試用例的過(guò)程中我們更能對(duì)整個(gè)系統(tǒng)了解,也能夠幫助我們寫代碼;然后我們一點(diǎn)點(diǎn)的寫,寫一部分測(cè)試一下,保證每次新寫的代碼都能正確運(yùn)行,從而當(dāng)代碼寫完了,系統(tǒng)調(diào)試也完畢了。這樣的情況下可以認(rèn)為我們沒(méi)有在調(diào)試上花時(shí)間,我們把時(shí)間花在測(cè)試和編寫代碼上了。

 

  3. 以前認(rèn)為代碼當(dāng)中注釋越多越好。Martin Flower又一次給我們教訓(xùn)說(shuō),寫注釋是因?yàn)槟愕拇a已經(jīng)不能告訴代碼閱讀者他的真實(shí)意思了。是的,好的代碼可以通過(guò)很多方式表達(dá)其自身的含義,例如變量的名稱,函數(shù)的名稱等;就如一個(gè)比較條件判斷來(lái)說(shuō)吧,我們有必要的情況下將這個(gè)即使很短的條件抽取一個(gè)方法,然后用方法名稱來(lái)告訴讀者判斷的真實(shí)意義,如果這里直接使用條件判斷就要讓讀者迷惑半天,當(dāng)然這里的前提是給變量和函數(shù)起一個(gè)合適的名字,這是考驗(yàn)程序員真功夫的地方了。另外,這里說(shuō)的不是說(shuō)寫注釋不好,如我的目的是如果代碼可以描述意義了,注釋就不需要寫了,這樣就讓你省了一件事情:保證代碼和注釋的同步,這不是更好。

 

  4. 在之前我也認(rèn)為重構(gòu)會(huì)花費(fèi)很大代碼,因?yàn)槲覀円斫獯a,重新編寫;但為了修改BUG,Martin Flower告訴我們重構(gòu)是最快的。也許不相信,我也不相信,但他說(shuō)的有道理,容易修改的BUG,當(dāng)然早就被修改了,那么剩下的BUG就很難找了,主要因?yàn)榇a中的邏輯不清楚,重構(gòu)可以改變這種情況,讓我們的代碼有條有理,那么當(dāng)然BUG就無(wú)處藏身了。

 

  5. 勇于接受變化。以前認(rèn)為用戶頻繁的變化需求是不可理喻,實(shí)際上是我們自己不可理喻,他們花錢當(dāng)然需要能提供高質(zhì)量的服務(wù);而Martin Flower認(rèn)為不用怕改變,我們有重構(gòu)工具,重構(gòu)可以讓我們代碼任何時(shí)候都是清楚的,容易修改的,那么變化是件快樂(lè)的事情不再象以前那樣艱難了。

 

  6. 重構(gòu)與性能不是是對(duì)立的。重構(gòu)讓代碼容易理解,而性能讓代碼變的難以理解,不過(guò)我們?cè)陂_(kāi)始的時(shí)候應(yīng)該考慮怎么樣讓代碼容易理解和維護(hù),這樣我們可以在后面適當(dāng)?shù)臅r(shí)候?qū)Υa的某部分進(jìn)行輕松的性能改進(jìn)工作。本人做性能改進(jìn)工作有段時(shí)間了,想從龐大的雜亂無(wú)章的、不熟悉的代碼中找出性能的bottleneck的確不是一件容易的事情,我需要的是理解代碼,理解流程,那么如果一個(gè)結(jié)構(gòu)很好的代碼對(duì)于我來(lái)說(shuō)就好對(duì)付多了。因此他們不是對(duì)立的,性能以重構(gòu)為基礎(chǔ)的。

  其實(shí)通過(guò)重構(gòu),最主要的目的是讓我們的代碼更清晰,更輕巧,更容易被維護(hù),那么也就是我們有良好的代碼,于是我們還懼怕什么,什么都可以輕松搞定。同樣《重構(gòu)》認(rèn)為代碼隨時(shí)都是清晰的、輕巧的,一般你的代碼不再具有以上特點(diǎn),那么我們就需要使用重構(gòu)了。