系统重构笔记
2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
重構(gòu)概念
在不改變軟件可觀察行為的前提下,對(duì)軟件內(nèi)部結(jié)構(gòu)的一種調(diào)整,提高其可理解性,降低修改成本。
重構(gòu)節(jié)奏
測(cè)試、小修改、測(cè)試、小修改......正是這種節(jié)奏讓重構(gòu)得以快速安全而安全的前行。
構(gòu)筑測(cè)試體系
如果想要重構(gòu),我們必須擁有一個(gè)良好的測(cè)試環(huán)境。編寫(xiě)優(yōu)良的測(cè)試程序,可以極大的提升編程速度和代碼質(zhì)量,即使不進(jìn)行重構(gòu)也一樣如此。
每當(dāng)我們收到一個(gè)bug報(bào)告時(shí),請(qǐng)先寫(xiě)一個(gè)單元測(cè)試來(lái)暴露bug。
測(cè)試是一種風(fēng)險(xiǎn)驅(qū)動(dòng)的行為,測(cè)試的目的是希望找出現(xiàn)在或未來(lái)才可能出現(xiàn)的錯(cuò)誤。 測(cè)試的要訣是:測(cè)試你最擔(dān)心出錯(cuò)的部分。這樣你就能從測(cè)試工作中得到最大的利益。
“花費(fèi)合理的時(shí)間找出大多數(shù)的bug”好過(guò)“窮盡一生抓出所有bug”。
重新組織函數(shù)
-
重復(fù)代碼 重復(fù)代碼應(yīng)該考慮將其提煉到一個(gè)獨(dú)立的函數(shù)或類中。
-
過(guò)長(zhǎng)函數(shù) 當(dāng)我們看見(jiàn)一個(gè)過(guò)長(zhǎng)的函數(shù)或者需要一段注釋才能讓人理解其用途的代碼時(shí),我們就需要將這段代碼放到一個(gè)獨(dú)立的函數(shù)中。 一個(gè)函數(shù)多長(zhǎng)才算合適?在我看來(lái)長(zhǎng)度不是問(wèn)題,關(guān)鍵在于函數(shù)名稱和函數(shù)體之間的語(yǔ)義距離。如果提煉可以強(qiáng)化代碼清晰度,那就去做,就算函數(shù)名稱比提煉出來(lái)的代碼還要長(zhǎng)也無(wú)所謂。
-
內(nèi)聯(lián)函數(shù) 有時(shí)候會(huì)遇到某些函數(shù),其內(nèi)部代碼和函數(shù)名稱同樣清晰易讀,我們就可以去掉這個(gè)函數(shù)直接使用其中代碼。
-
內(nèi)聯(lián)臨時(shí)變量 如果發(fā)現(xiàn)一個(gè)臨時(shí)變量只被一個(gè)簡(jiǎn)單表示式賦值一次,并且妨礙了其他重構(gòu)手法,我們就應(yīng)該讓他內(nèi)聯(lián)化。 直接將變量聲明成final的,可以檢查變量是否真的是被賦值了一次。
-
以查詢來(lái)取代臨時(shí)變量
-
引入解釋性臨時(shí)變量 將復(fù)雜表達(dá)式的結(jié)果放到一個(gè)臨時(shí)變量,以變量名稱來(lái)解釋表達(dá)式用途。
-
分解臨時(shí)變量
在對(duì)象之間搬移特性
在對(duì)象設(shè)計(jì)過(guò)程中,決定把“責(zé)任”放在哪里是非常總要的。這曾經(jīng)讓我非常苦惱,但是現(xiàn)在我知道,在這種情況下,可以運(yùn)用重構(gòu),改變?cè)械脑O(shè)計(jì)。
-
搬移函數(shù) “搬移函數(shù)”是重構(gòu)理論的支柱。如果一個(gè)類有太多行為,如果一個(gè)類和另一個(gè)類高度耦合,我們就需要搬移函數(shù)。
-
搬移新的字段 隨著系統(tǒng)的發(fā)展,你會(huì)發(fā)現(xiàn)自己需要新的類,并將現(xiàn)有的工作拖到新的類中。如果發(fā)現(xiàn)對(duì)于一個(gè)字段,在其所駐類之外的另一個(gè)類中都有更多函數(shù)使用了它,我就會(huì)考慮搬移這個(gè)字段。
-
提煉類 一個(gè)類應(yīng)該是一個(gè)清晰的抽象,處理一些明確的責(zé)任。
簡(jiǎn)化表達(dá)式
可以將一個(gè)復(fù)雜的條件邏輯分解成若干小塊。這樣可以使得分支邏輯和操作細(xì)節(jié)分離。
-
分解條件表達(dá)式 分解表達(dá)式可以突出條件邏輯,更清晰地表明每個(gè)分支的作用,并突出每個(gè)分支的原因。 做法:將分支語(yǔ)句提煉出來(lái),構(gòu)成一個(gè)獨(dú)立的函數(shù)。
-
合并表達(dá)式 有時(shí)會(huì)發(fā)現(xiàn)一串的表達(dá)式檢查條件各不相同,但最終行為卻一致。如果這樣就需要使用“邏輯與”或“邏輯或”合并表達(dá)式。
-
合并重復(fù)的條件片段 當(dāng)所有分支都會(huì)執(zhí)行相同代碼時(shí),就需要將這段代碼搬移到條件表達(dá)式之外了。這樣我們能更加清晰的知道,那些東西是隨著條件變化而變化的、那些是不變的。
-
移除控制標(biāo)記 控制標(biāo)記可以使用break或continue來(lái)代替,還可以使用return直接返回。
-
以衛(wèi)語(yǔ)句來(lái)取代嵌套表達(dá)式 可以讓代碼邏輯看起來(lái)更加的清晰。
-
以多態(tài)來(lái)取代條件表達(dá)式 多態(tài)的好處在于:如果你需要根據(jù)對(duì)象的不同類型來(lái)采取不同的行為,多態(tài)使你不必寫(xiě)明顯的條件表達(dá)式。
簡(jiǎn)化函數(shù)調(diào)用
- 改函數(shù)名 函數(shù)的名稱應(yīng)該準(zhǔn)確的表達(dá)它的用途。給函數(shù)命名有一個(gè)好的辦法:首先考慮應(yīng)該給函數(shù)寫(xiě)上一句這樣的注釋,然后在想辦法將注釋變成函數(shù)名稱。
-
移除參數(shù) 參數(shù)代表著函數(shù)所需的信息,不同的參數(shù)值有不同的意義。如果不去掉多余的參數(shù),就會(huì)讓每一位調(diào)用者多費(fèi)一份心。
-
將查詢函數(shù)和修改函數(shù)分離 任何有返回值的函數(shù),都不因該有看到的副作用。
-
引入?yún)?shù)對(duì)象 為了縮短參數(shù)列,我們可以使用一個(gè)對(duì)象來(lái)包裝所有的參數(shù)。這樣可以降低理解和修改函數(shù)代碼的難度。
-
以異常來(lái)取代錯(cuò)誤碼 如果調(diào)用者有責(zé)任在調(diào)用前檢查必要狀態(tài),就拋出非受控異常。
處理概括關(guān)系
-
劃分邊界 確定各個(gè)字段、方法應(yīng)該處于子類還是超類也是我們經(jīng)常需要注意的一個(gè)點(diǎn)。
-
提煉子類、超類和接口
-
折疊繼承體系 有時(shí)我們會(huì)發(fā)現(xiàn)某個(gè)子類并沒(méi)有帶來(lái)該有的價(jià)值時(shí),我們就需要將子類的超類合并。
-
塑造模板函數(shù) 你有一些子類,其中相應(yīng)的某些函數(shù)以相同順序執(zhí)行類似的操作,但是各個(gè)操作細(xì)節(jié)上有所不同。將這些操作分別放進(jìn)獨(dú)立函數(shù)中,并保證他們有相同的簽名,于是原函數(shù)也變得相同了,然后將原函數(shù)移至超類。
-
以委托取代繼承 當(dāng)某個(gè)子類只使用接口中的一部分,或者不使用繼承而來(lái)的數(shù)據(jù)時(shí),我們可以在子類新建一個(gè)字段用以保存超類:調(diào)整子類函數(shù),令他改而委托超類;然后去掉兩者間的繼承關(guān)系。
大型重構(gòu)
- 梳理并分解機(jī)場(chǎng)體系
- 將過(guò)程化設(shè)計(jì)轉(zhuǎn)化為對(duì)象設(shè)計(jì)
- 提煉繼承體系
重構(gòu)要點(diǎn)
參考
《重構(gòu)改善既有代碼設(shè)計(jì)》
為監(jiān)控而生的多級(jí)緩存框架 layering-cache這是我開(kāi)源的一個(gè)多級(jí)緩存框架的實(shí)現(xiàn),如果有興趣可以看一下
轉(zhuǎn)載于:https://my.oschina.net/u/3748347/blog/2992764
總結(jié)
- 上一篇: Android端IM应用中的@人功能实现
- 下一篇: 系统相关的信息模块: import sy