RedRain的簡(jiǎn)書:http://www.reibang.com/users/29e03e6ff407/latest_articles
一.創(chuàng)建
1. 如果類中有太多的構(gòu)造函數(shù),客戶要弄清應(yīng)該調(diào)用其中的哪一個(gè)會(huì)非常困難.
- 方法之一是應(yīng)用
提煉類
或提煉子類
這樣的重構(gòu), 減少構(gòu)造函數(shù)的數(shù)量. - 方法之二是通過用
Creation Method替換構(gòu)造函數(shù)
重構(gòu)來澄清構(gòu)造函數(shù)的意圖.
2.如果對(duì)象創(chuàng)建過程中使用的數(shù)據(jù)和代碼在許多類中都存在
-
將創(chuàng)建知識(shí)搬移到Factory
重構(gòu)可以把創(chuàng)建代碼和數(shù)據(jù)合并為一個(gè)Factory來減少創(chuàng)建代碼的蔓延.
3.如果類層次中有多個(gè)類都類似地實(shí)現(xiàn)了一個(gè)方法, 只是對(duì)象的創(chuàng)建步驟不同
- 首先通過用
Factory Method
引入多態(tài)創(chuàng)建
重構(gòu)來刪除重復(fù)代碼.
4.確保客戶代碼通過一個(gè)公共接口與多個(gè)類的實(shí)例進(jìn)行通信
- Factory封裝類
5.簡(jiǎn)化對(duì)象結(jié)構(gòu)的構(gòu)造
- 用Builder封裝Composite重構(gòu)說明了如何用Builder模式提供構(gòu)造Composite模式的更簡(jiǎn)單而且不易出錯(cuò)的方式.
二.簡(jiǎn)化
為了使代碼簡(jiǎn)單,必須要思考它復(fù)雜在什么地方, 并要不停地問:"怎樣能更簡(jiǎn)單一些?"
通常情況下, 可以考慮一種完全不同的解決方案來簡(jiǎn)化代碼. 這里展示了簡(jiǎn)化方法
,狀態(tài)轉(zhuǎn)換
和樹型結(jié)構(gòu)
的不同方案.
1.更有效地表達(dá)方法實(shí)現(xiàn)的功能以及如何實(shí)現(xiàn)這些功能
-
組合方法
重構(gòu)用來生成更優(yōu)雅的方法 - 一個(gè)組合方法由對(duì)一些命名良好的方法的調(diào)用組成
- 這些方法數(shù)據(jù)實(shí)現(xiàn)細(xì)節(jié)的同一個(gè)曾銘.
2.算法經(jīng)常會(huì)因?yàn)槎喾N變化而變得復(fù)雜
- 用
Strategy替換條件邏輯
重構(gòu)展示了如何通過把算法分解成單獨(dú)的類來簡(jiǎn)化它. - 如何算法并沒有復(fù)雜到需要使用Strategy,只會(huì)使設(shè)計(jì)更加復(fù)雜
3.一個(gè)類中有過多的特殊情況或裝飾邏輯
-
將裝飾邏輯搬移到Decorator
重構(gòu)描述了如何判斷是否需要應(yīng)用Decorator, 并展示了如何把裝飾功能從類的核心職責(zé)中分離出來.
4.控制狀態(tài)轉(zhuǎn)換的邏輯往往會(huì)變得越來越復(fù)雜.
- 用
State替換狀態(tài)改變條件語句
重構(gòu)描述了如何簡(jiǎn)化復(fù)雜的狀態(tài)轉(zhuǎn)換邏輯, 并幫助確定邏輯是否復(fù)雜到應(yīng)該應(yīng)用State模式
5.針對(duì)樹型結(jié)構(gòu)的重構(gòu)方法
- Composite替換隱含樹, 展示了Composite模式如何能夠簡(jiǎn)化客戶程序?qū)湫谓Y(jié)構(gòu)的創(chuàng)建和交互
6.完全簡(jiǎn)化一個(gè)用來控制哪組行為應(yīng)該執(zhí)行的switch語句
- 用Command替換條件調(diào)度程序.
三.泛化
泛化是把特殊代碼轉(zhuǎn)換成 通用目的 代碼的過程. 泛化代碼的產(chǎn)生往往是重構(gòu)的結(jié)果. 其最常見的動(dòng)機(jī)就是去除重復(fù)代碼, 其次是為了簡(jiǎn)化或澄清代碼.
1. 去除同一類層次結(jié)構(gòu)中子類所包含的相似方法中的重復(fù)代碼.
-
Template Method
重構(gòu),如果這些方法基本是遵循一定的步驟, 一定的順序, 即使這些步驟有少許區(qū)別, 也可以通過在超類中定義Template Method把這些區(qū)別與泛化的內(nèi)容分開
2.一個(gè)類層次結(jié)構(gòu)中存在不恰當(dāng)?shù)腃omposite[組合]實(shí)現(xiàn)的時(shí)候.
-
提取Composite
重構(gòu)是提煉超類重構(gòu)的具體應(yīng)用, 通過把Composite提取成超類, 子類就可以共享Composite的一個(gè)泛化實(shí)現(xiàn).
3.如果系統(tǒng)含有處理一個(gè)對(duì)象代碼, 同時(shí)又含有處理一組相同對(duì)象的代碼(通常是某個(gè)集合).
- 用
Composite替換一/多之分
重構(gòu)可以幫助我們產(chǎn)生一個(gè)泛化的解決方案, 可以無差別處理一個(gè)或多個(gè)對(duì)象
4.負(fù)責(zé)通知的對(duì)象和被通知的對(duì)象緊緊的耦合在一起.
- 用
Observer替換硬編碼的通知
重構(gòu)是用泛化替代特定方案的經(jīng)典實(shí)例.為了允許其他類的實(shí)例也可以被通知, 我們可以把代碼重構(gòu)成使用Observer.
5.當(dāng)客戶代碼使用不同的接口與相似的類交互時(shí), 往往就會(huì)產(chǎn)生復(fù)雜的處理邏輯.
- 應(yīng)用
通過Adapter[適配器]統(tǒng)一接口
重構(gòu), 客戶代碼就可以通過一個(gè)泛化的接口與相似類交互, 這就為去除客戶代碼中重復(fù)處理邏輯的其他重構(gòu)鋪平了道理.
6.當(dāng)一個(gè)類作為組件,類庫,API或其他實(shí)體的多個(gè)版本的Adapter的時(shí)候, 這個(gè)類就會(huì)包含重復(fù)代碼, 并且設(shè)計(jì)也不會(huì)簡(jiǎn)單.
- 應(yīng)用
提取Adapter
重構(gòu)可以產(chǎn)生實(shí)現(xiàn)了通用接口并適配單一版本代碼的類.
四.保護(hù)
有些重構(gòu)能夠改進(jìn)對(duì)現(xiàn)有代碼的保護(hù), 但不能改變現(xiàn)有代碼的行為. 應(yīng)用這些重構(gòu)的動(dòng)機(jī)可能是改進(jìn)對(duì)現(xiàn)有代碼的保護(hù), 或者是標(biāo)準(zhǔn)的重構(gòu)動(dòng)機(jī), 如減少重復(fù)代碼或簡(jiǎn)化澄清代碼.
1.用類替換類型代碼
2.如果想要控制一個(gè)類被實(shí)例化多個(gè)對(duì)象, 減少內(nèi)存使用量或改進(jìn)性能.
- 用Singleton限制實(shí)例化.
- Singleton模式的一個(gè)很不好的動(dòng)機(jī)是使一段代碼能夠訪問很難到達(dá)的信息. 一般情況下, 只有在性能分析程序告訴你值得這么做的時(shí)候,才會(huì)用到
Singleton限制實(shí)例化
3.如果代碼中包含很多的邏輯來檢查相同的null值.
- 引入Null Object重構(gòu)可以幫助我們使用另一個(gè)方式讓代碼避免使用null值. 從而簡(jiǎn)化代碼.
五.聚集操作
Collecting Parameter是這樣一個(gè)對(duì)象, 他會(huì)訪問不同的方法, 以便從中聚集信息, 被訪問的方法可能處于一個(gè)或多個(gè)對(duì)象中. 每個(gè)被訪問的方法都會(huì)為Collecing Parameter提供信息. 在訪問了所有的相關(guān)方法之后, 我們就可以從Collecting Parameter中獲取聚集的信息.
1.當(dāng)你擁有一個(gè)很長的,包含很多行為來聚集信息的代碼的方法時(shí).
- 利用
將聚集操作搬移到Collecting Parameter
重構(gòu)與組合方法
重構(gòu)一起使用, 會(huì)達(dá)到最好的效果. 應(yīng)該把接收并寫入Collecting Parameter的代碼提煉成方法, 這樣就可以把原方法分解成幾個(gè)小部分, 每一部分處理聚集的一小塊.
2.Visitor模式
Collecting Parameter模式的能力是從幾個(gè)對(duì)象中聚集信息, 從這一點(diǎn)上來看, 它和Visitor模式很相似. 不同的是
- 被Visitor訪問的對(duì)象把自己傳入Visitor的實(shí)例.
- 被Collecting Parameter訪問的對(duì)象通過簡(jiǎn)單地調(diào)動(dòng)Collecting Parameter上的方法來為它提供信息.
Visitor模式只適用于從多個(gè)對(duì)象中聚集信息, 而不適用于一個(gè)對(duì)象的情況. 它也更適用于從不同的對(duì)象中聚集信息, 而不適用于相似的對(duì)象(例如,共享相同接口的對(duì)象). 因?yàn)閂isitor實(shí)現(xiàn)起來要比Collecting Parameter復(fù)雜. 所以要使用Visitor之前先考慮是否可以使用Collecting Parameter.
六.實(shí)用重構(gòu)
1.使構(gòu)造函數(shù)彼此調(diào)用,去除構(gòu)造函數(shù)中重復(fù)代碼.
-
鏈構(gòu)造函數(shù)
, 這個(gè)重構(gòu)會(huì)在用Creation Method替換構(gòu)造函數(shù)
重構(gòu)中用到
2.當(dāng)需要一個(gè)超類或接口來共享子類的相同接口時(shí).
-
統(tǒng)一接口
重構(gòu)就可以派上用場(chǎng). 應(yīng)用這一重構(gòu)的通常動(dòng)機(jī)是能夠多態(tài)地使用對(duì)象.重構(gòu)將裝飾功能搬移到Decorator
和將聚集操作搬移到Visitor
都會(huì)使用到這一重構(gòu)
3.一個(gè)字段被賦值為局部實(shí)例化的值, 而你更希望把這個(gè)值作為參數(shù)傳遞進(jìn)來.
- 使用
提取參數(shù)
重構(gòu). 這在很多情況下都是很有幫助的, 尤其是將裝飾功能搬移到Decorator
重構(gòu), 他會(huì)在應(yīng)用了以委托取代繼承
重構(gòu)后, 馬上使用這一重構(gòu).