一. 這本書在談什么?
《重構(gòu)》是程序員里面很經(jīng)典的一本書,有人曾說,做面向?qū)ο箝_發(fā),就是左手設(shè)計(jì)模式,右手重構(gòu),說的很在理。其實(shí)重構(gòu)的方法和邏輯也都是基于設(shè)計(jì)原則的,比如單一職責(zé)原則,最少知識(shí)原則。當(dāng)然,重構(gòu)的前提是在不改變對(duì)原有系統(tǒng)的功能的基礎(chǔ)之上做的設(shè)計(jì)優(yōu)化,可以提高其可理解性,降低其修改成本。
二. 這本書細(xì)節(jié)部分都講了什么?
1.重構(gòu)的方法論
- 重構(gòu)也是避免你的代碼越來越復(fù)雜和難以維護(hù)的重要手段,當(dāng)你發(fā)現(xiàn)你的代碼已經(jīng)很難添加新的功能時(shí),就要考慮是否重構(gòu)了。
- 作者提到一個(gè)重構(gòu)的關(guān)鍵做法,就是測(cè)試,引入測(cè)試,是確保你的重構(gòu)能夠正常和確保原有系統(tǒng)功能的重要保證。而且提倡你小步快跑,而不是每次重構(gòu)都變得難以恢復(fù),應(yīng)該是改一點(diǎn),測(cè)一點(diǎn),直到全部重構(gòu)完成。另外,測(cè)試不需要測(cè)試所有的功能,而應(yīng)該放在你覺得容易出錯(cuò)的地方即可。
- 改進(jìn)設(shè)計(jì)的一個(gè)重要方向就是消除重復(fù)代碼。
- 良好的設(shè)計(jì)是快速開發(fā)的根本
- 重構(gòu)往往是把大型對(duì)象拆成多個(gè)小型對(duì)象,把大型函數(shù)拆成多個(gè)小型函數(shù),這個(gè)和架構(gòu)設(shè)計(jì)里面常說的“分而治之”有異曲同工之妙。
2. 幾個(gè)關(guān)鍵的認(rèn)知
- 讓代碼自解釋,好的代碼應(yīng)該是不需要注釋就能讓別人能夠看懂,明白你的代碼邏輯的,因此,包括變量名、方法名等都應(yīng)該做好清楚,明白。
- 函數(shù)和它說使用的數(shù)據(jù)應(yīng)該放在一起,如果出現(xiàn)函數(shù)和數(shù)據(jù)分離的情況,就要考慮重構(gòu)了。
- 如果if/else,switch出現(xiàn)的很多,也要考慮重構(gòu),重構(gòu)的技巧是使用多態(tài)。
3. 怎么判斷代碼是否要重構(gòu)
- 重復(fù)代碼
- 如同一類中的兩個(gè)函數(shù)有相同的表達(dá)式:抽取出來做獨(dú)立函數(shù);
- 兩個(gè)互為兄弟的子類內(nèi)含相同的表達(dá)式: 推入超類;
- 兩個(gè)不相關(guān)的類出現(xiàn)重復(fù)代碼:提煉到一個(gè)獨(dú)立類中。
- 過長(zhǎng)代碼
- 拆分然后讓小函數(shù)有容易理解的名字;
- 有過多注釋時(shí):拆分為獨(dú)立函數(shù);
- 條件和循環(huán):提煉到獨(dú)立函數(shù)。
- 過大的類
- 抽取和拆分類,將數(shù)據(jù)和行為移到一個(gè)獨(dú)立的領(lǐng)域?qū)ο笾小?/li>
- 過長(zhǎng)的參數(shù)列
- 太長(zhǎng)的參數(shù)列難以理解,太多參數(shù)容易造成前后不一致、不易使用,而且一旦你需要更多數(shù)據(jù),就不得不修改它。
- 發(fā)散式變化
- 如果一個(gè)類經(jīng)常因?yàn)椴煌脑蛟诓煌姆较蛏献兓?,那就需要將變化的部分遷移到一個(gè)新類中。
6.霰彈式修改
- 如果遇到變化,需要在許多不同的小類中作出很多小修改,那就需要把一系列相關(guān)行為放到一個(gè)類中。
- 依戀情節(jié)
- 將數(shù)據(jù)和對(duì)數(shù)據(jù)的操作行為包裝在一起。這也是封裝的終極追求。
- 數(shù)據(jù)泥團(tuán)
- 總是綁在一起的數(shù)據(jù)應(yīng)該擁有他們自己的對(duì)象
- switch
- 面向?qū)ο蟮囊粋€(gè)明顯特征是:少用switch,應(yīng)該用多態(tài)來替換它。當(dāng)然,如果只是在一個(gè)單一函數(shù)中有些選擇事例,且不會(huì)變化,那就不需要用多態(tài)。
10.其他一些情況
- 過度使用委托,如中間委托類承擔(dān)了原來類中大半的函數(shù)了,那就應(yīng)該取消中間類,直接讓兩個(gè)對(duì)象發(fā)生關(guān)系
- 過度使用繼承,會(huì)造成耦合嚴(yán)重,這時(shí)候應(yīng)該考慮去掉繼承關(guān)系
4. 重構(gòu)的一些小技巧
- 對(duì)于臨時(shí)變量,如果他們被賦值超過一次,那就意味著他們?cè)诤瘮?shù)中承擔(dān)了一個(gè)以上的責(zé)任。應(yīng)該替換成多個(gè)臨時(shí)變量。
- 避免對(duì)參數(shù)進(jìn)行賦值。(跟使用被傳入對(duì)象的操作不同)
- 數(shù)據(jù)隱藏,不要使用public來修飾數(shù)據(jù)。
- 將查詢函數(shù)和修改函數(shù)分離
三. 總結(jié)
其實(shí)重構(gòu)沒有想象中那么復(fù)雜,遵循的原則也無非的單一職責(zé)、最少知識(shí)原則、封裝等基礎(chǔ)的面向?qū)ο蟮母拍?,重?gòu)不過是按照這些原則來開展代碼優(yōu)化的具體實(shí)踐,最重要的還是要在工作中結(jié)合使用,將這些知識(shí)變成自己的技能和習(xí)慣,寫出好的代碼,才能在以后運(yùn)維中少吃點(diǎn)虧。