提煉函數(shù)Extract Function:將代碼提煉到函數(shù)中。

image.png
- 動(dòng)機(jī):“將意圖與實(shí)現(xiàn)分開(kāi)”:如果你需要花時(shí)間瀏覽一段代碼才能弄清它在干什么,那么就應(yīng)該將其提煉到一個(gè)函數(shù)中,并根據(jù)它所做的事為其命名。以后再讀到這段代碼時(shí),你一眼就能看到函數(shù)的用途,大多數(shù)時(shí)候根本不需要關(guān)心函數(shù)如何達(dá)成其用途(這是函數(shù)體內(nèi)干的事)。
- 新函數(shù)命名:以它“做什么”來(lái)命名,而不是以它“怎樣做”命名。
內(nèi)聯(lián)函數(shù)inline Function:提煉函數(shù)的反向重構(gòu)。

image.png
- 動(dòng)機(jī):函數(shù)間調(diào)用時(shí),簡(jiǎn)介層過(guò)度簡(jiǎn)單,過(guò)度運(yùn)用。a->b b->c c->d. ? a->d。那么去掉中間層,直接調(diào)用函數(shù)本體。
提煉變量Extract Variable:提煉變量。

image.png
- 使用:
- 在方法內(nèi),抽取成單獨(dú)的表達(dá)式
- 在類內(nèi),判斷可否將單獨(dú)的表達(dá)式提取函數(shù)
內(nèi)聯(lián)變量Inline Variable:提煉變量的反向重構(gòu)。

image.png
- 動(dòng)機(jī):在一個(gè)函數(shù)內(nèi)部,變量能給表達(dá)式提供有意義的名字,因此通常變量事好東西。但有時(shí)候,這個(gè)名字并不比表達(dá)式更具表現(xiàn)力。還有些時(shí)候,變量可能會(huì)妨礙重構(gòu)附近的代碼。若果真如此,就應(yīng)該通過(guò)內(nèi)聯(lián)的手法消除變量
改變函數(shù)聲明Change Function Declaration:用于修改函數(shù)的名字,或者添加刪減參數(shù)。

image.png
- 包含情形:
- 函數(shù)和參數(shù)改名:好的名字更易理解。
- 函數(shù)參數(shù)的增減,讓參數(shù)列表更適合其上下文。
封裝變量 Encapsulate Variable。

image.png
- 動(dòng)機(jī):如果數(shù)據(jù)的可訪問(wèn)范圍很大,一旦對(duì)改數(shù)據(jù)進(jìn)行變化,那么所有引用該數(shù)據(jù)的代碼都需要同時(shí)修改。這就類似于全局?jǐn)?shù)據(jù)的修改。
- 做法:
- 創(chuàng)建封裝函數(shù),在其中訪問(wèn)和更新變量值。將對(duì)變量的引用改為對(duì)函數(shù)的調(diào)用。
- 因?yàn)樵诟拿虬嵋坪瘮?shù)的過(guò)程中,總是可以比較容易地保留舊函數(shù)作為轉(zhuǎn)發(fā)函數(shù)(即舊代碼調(diào)用舊函數(shù),舊函數(shù)再調(diào)用新函數(shù))。
變量改名Rename Variable:改變變量名字。

image.png
- 動(dòng)機(jī):好的名字使得程序更易理解。
引入?yún)?shù)對(duì)象Introduce Parameter Object:把常在一起出沒(méi)的參數(shù)組合成一個(gè)對(duì)象。

image.png
- 動(dòng)機(jī):數(shù)據(jù)項(xiàng)之間的關(guān)系變得明晰,組織成一個(gè)統(tǒng)一的數(shù)據(jù)結(jié)構(gòu),今后數(shù)據(jù)項(xiàng)的增減,在調(diào)用處不需作出改變。再就是調(diào)用處的參數(shù)列表縮短,
函數(shù)組合成類Combine Functions into Class:把函數(shù)和它們操作的數(shù)據(jù)一起組合成類。

image.png
- 動(dòng)機(jī):如果發(fā)現(xiàn)一組函數(shù)形影不離地操作同一塊數(shù)據(jù)(通常是將這塊數(shù)據(jù)作為參數(shù)傳遞進(jìn)函數(shù)),我就認(rèn)為,是時(shí)候組件一個(gè)類了。類能明確地給這些函數(shù)提供一個(gè)共用的環(huán)境,在對(duì)象內(nèi)部調(diào)用這些函數(shù)可以少穿許多參數(shù),從而簡(jiǎn)化函數(shù)調(diào)用,并且這樣一個(gè)對(duì)象也可以更方便地傳遞給系統(tǒng)的其他部分。
函數(shù)組合成變換Combine Functions into Transform:將函數(shù)組合成變換式,這對(duì)于處理只讀數(shù)據(jù)尤為便利。

image.png
- 動(dòng)機(jī):在軟件中,經(jīng)常需要把數(shù)據(jù)“喂”給一個(gè)程序,讓它再計(jì)算出各種派生信息。這些派生數(shù)值可能會(huì)在幾個(gè)不同地方用到,因此這些計(jì)算邏輯也常會(huì)在用到派生數(shù)據(jù)的地方重復(fù)。我更愿意把所有計(jì)算派生數(shù)據(jù)的邏輯收攏到一處,這樣始終可以在固定的地方找到和更新這些邏輯,避免到處重復(fù)。一個(gè)方式是采用數(shù)據(jù)變換函數(shù):這種函數(shù)接受源數(shù)據(jù)作為輸入,計(jì)算出所有的派生數(shù)據(jù),將派生數(shù)據(jù)以字段形式填入輸出數(shù)據(jù)。有了變換函數(shù),我就始終只需要到變換函數(shù)中去檢查計(jì)算派生數(shù)據(jù)的邏輯。
拆分階段Split Phase:將模塊組成界限分明的處理階段。

image.png
- 動(dòng)機(jī):每當(dāng)看見(jiàn)一段代碼在同時(shí)處理兩件不同的事,我就想把它拆分成個(gè)字獨(dú)立的模塊,因?yàn)檫@樣到了需要修改的時(shí)候,我就可以單獨(dú)處理每個(gè)主題,而不必同時(shí)在腦子里考慮兩個(gè)不同的主題。如果運(yùn)氣夠好的話,我可能只需要修改其中一個(gè)模塊,完全不用回憶起另一個(gè)模塊的諸般細(xì)節(jié)。
- 做法:最簡(jiǎn)單的拆分方法之一,就是把一大段行為分成順序執(zhí)行的兩個(gè)階段??赡苣阌幸欢翁幚磉壿嫞漭斎霐?shù)據(jù)的格式不符合計(jì)算邏輯的要求,所以你得先對(duì)輸入數(shù)據(jù)做一番調(diào)整,使其便于處理。也可能是你把數(shù)據(jù)處理邏輯分成順序執(zhí)行的多個(gè)步驟,每個(gè)步驟負(fù)責(zé)的任務(wù)全然不同。