《《重構(gòu)2》這本書是我覺得非常有必要看的,對于自己寫代碼有著比較大的影響,力薦。結(jié)合書中和自己實踐提煉和總結(jié)一些內(nèi)容分享出來奢米。重構(gòu)分為服務(wù)級別的重構(gòu)和代碼級別的重構(gòu)抓韩,《重構(gòu)2》這里面主要是說代碼級別的。強如阿里鬓长,發(fā)展的過程中也會出現(xiàn)臃腫問題谒拴,后續(xù)他們把服務(wù)進(jìn)行了分布式改造和服務(wù)化改造。如下摘抄《淘寶技術(shù)這10年》的原話涉波。
1. 為什么重構(gòu)
1.1 重構(gòu)是什么
重構(gòu)指在不改變代碼外在行為的前提下英上,對代碼做出修改,以改進(jìn)程序的內(nèi)部結(jié)構(gòu)啤覆。
1.2 重構(gòu)的作用
a苍日、改進(jìn)軟件設(shè)計。
b城侧、使軟件(代碼)更容易理解易遣。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? c、幫助找到bug嫌佑。
d豆茫、提高編程速度。
2. 何時重構(gòu)
2.1 簡單來說屋摇,重構(gòu)不需要刻意去安排時間揩魂,不用為了重構(gòu)而重構(gòu),重構(gòu)是為了把某件事情更好地完成炮温;
2.2 三次法則火脉,即事不過三,同樣的程序出現(xiàn)多次就可以考慮重構(gòu)了柒啤;
2.3 添加新功能時重構(gòu)倦挂;
2.4 修補問題功能時重構(gòu);
2.5 復(fù)審代碼時重構(gòu)担巩;
3. 重構(gòu)什么
3.1 神秘的命名
命名不合理給閱讀帶來很大的困擾方援。給方法、模塊涛癌、變量和類一個好的名字犯戏,才能清晰地表達(dá)相應(yīng)的功能和用法。
3.2 重復(fù)的代碼
一旦有重復(fù)代碼存在拳话,閱讀這些重復(fù)的代碼時你就必須加倍仔細(xì)先匪,留意其間細(xì)微的差異。如果要修改重復(fù)代碼弃衍,你必須找出所有的副本來修改呀非。
3.3 過長的方法
方法越長,就越難理解镜盯。越不好維護(hù)姜钳。
3.4 過長的參數(shù)列表
過長的參數(shù)坦冠,不好理解和維護(hù)。
3.5 數(shù)據(jù)泥團
常掣缜牛可以在很多地方看到相同的三四項數(shù)據(jù):兩個類中相同的字段、許多方法簽名中相同的參數(shù)激涤。這些總是綁在一起出現(xiàn)的數(shù)據(jù)應(yīng)該擁有屬于它們自己的對象拟糕。
3.6 循環(huán)語句
循環(huán)已經(jīng)有點兒過時,看是否能用stream替代
3.7 冗贅的元素
可能有這樣一個方法倦踢,它的名字就跟實現(xiàn)代碼看起來一模一樣送滞;也可能有這樣一個類,根本就是一個簡單的方法辱挥。起初在編寫這個方法時犁嗅,期望它將來有一天會變大、變復(fù)雜晤碘,但那一天從未到來褂微。
3.8 夸夸其談通用性
當(dāng)有人說“噢,我想我們總有一天需要做這件事”园爷,并企圖以各式各樣的鉤子和特殊情況來處理一些非必要的事情宠蚂,這種壞味道就出現(xiàn)了。這么做的結(jié)果往往造成系統(tǒng)更難理解和維護(hù)童社。
3.9 臨時字段
類內(nèi)部某個字段僅為某種特定情況而設(shè)求厕。這樣的代碼有時讓人不易理解。
3.10 過大的類
如果想利用單個類做太多事情扰楼,其內(nèi)往往就會出現(xiàn)太多字段呀癣。一旦如此,重復(fù)代碼也就接踵而至了弦赖。
3.11 注釋
有時候注釋為了掩蓋代碼的壞味道项栏,作為“除臭劑”使用了。有時注釋就作為一個有壞味道的信號了腾节。
4. 重構(gòu)的技巧
4.1忘嫉、提煉方法;(反向重構(gòu)-內(nèi)聯(lián)方法)
使用場景如:方法過長案腺、代碼復(fù)用的角度
一個很好的技巧是:尋找注釋庆冕。就算只有一行代碼,如果它需要以注釋來說明劈榨,那也值得將它提煉到獨立方法中去访递。
4.2 提煉變量(反向重構(gòu)-內(nèi)聯(lián)變量)
如果表達(dá)式非常復(fù)雜而難以閱讀。這種情況下同辣,局部變量可以幫助我們將表達(dá)式分解為比較容易管理的形式拷姿。
4.3 引入?yún)?shù)對象
使用場景:數(shù)據(jù)泥團
4.4 以查詢?nèi)〈R時變量
使用場景:取代臨時變量惭载、方便提煉方法
4.5 提煉類 (反向重構(gòu)-內(nèi)聯(lián)類)
使用場景:數(shù)據(jù)泥團。一般類隨著責(zé)任不斷增加响巢,這個類會變得過分復(fù)雜描滔。很快,你的類就會變成一團亂麻踪古。
4.6 拆分循環(huán)
讓循環(huán)只做一件事情含长,但如果你在一次循環(huán)中做了多件不同的事,那么每當(dāng)需要修改循環(huán)時伏穆,你都得同時理解這多件事情拘泞。拆分循環(huán)有利于系統(tǒng)的完善。但是有一點枕扫,重構(gòu)完成之后陪腌,如果確實發(fā)現(xiàn)會造成性能問題,再合并回來烟瞧。一般情況下诗鸭,循環(huán)本身也很少成為性能瓶頸。
4.7 stream替換循環(huán)
使用場景:stream好處是燕刻,允許我們?nèi)ケ磉_(dá)我們想要完成什么而不是要怎樣做
4.8 移除死代碼
使用場景:無用代碼確實會帶來很多額外的思維負(fù)擔(dān)只泼。有可能以后又會需要這段代碼,就算真的發(fā)生卵洗,可以從版本控制系統(tǒng)里再次將它翻找出來请唱。
4.9 拆分變量
其他的如果它們被賦值超過一次,就意味它們在函數(shù)中承擔(dān)了一個以上的責(zé)任过蹂。同一個變量承擔(dān)兩件不同的事情十绑,降低可讀性。
4.10 分解條件表達(dá)式 (反向重構(gòu)-合并條件表達(dá)式)
將每個分支條件分解成新函數(shù)可以帶來更多好處:可以突出條件邏輯酷勺,更清楚地表明每個分支的作用本橙,并且突出每個分支的原因。
4.11 以衛(wèi)語句取代嵌套條件表達(dá)式
衛(wèi)語句取代嵌套條件表達(dá)式的精髓就是:給某一條分支以特別的重視脆诉。如果使用if-else結(jié)構(gòu)甚亭,你對if分支和else分支的重視是同等的。
4.12 以命令取代方法 (反向重構(gòu)-以方法取代命令)
適用場景例如:過長方法击胜,命令對象提供了更大的控制靈活性和更強的表達(dá)能力
4.13 方法上移 (反向重構(gòu)-方法下移)
避免重復(fù)代碼
4.14 提煉超類
如果我看見兩個類在做相似的事亏狰,可以利用基本的繼承機制把它們的相似之處提煉到超類。
4.15 委托取代子類 (類似-委托取代超類)
繼承給類之間引入了非常緊密的關(guān)系偶摔。與繼承關(guān)系相比暇唾,使用委托關(guān)系時接口更清晰、耦合更少。
5. 測試幫助重構(gòu)
要正確地進(jìn)行重構(gòu)策州,前提是得有一套穩(wěn)固的測試集合瘸味,以幫我發(fā)現(xiàn)難以避免的疏漏,這點很重要够挂,只要這方面吃過虧就能認(rèn)識到旁仿。
還有一個問題就是重構(gòu)代碼短期間收益不高,很不容易出kpi下硕,如果上頭不是很認(rèn)可丁逝,其實這個工作很不好做,改得不好很容易背鍋梭姓。