重構(gòu)圖形設(shè)計(jì)圖片_深入淺出設(shè)計(jì)模式epub_guisu,程序人生。 逆水行舟,不進(jìn)則退。
本文關(guān)鍵詞:重構(gòu)與模式,由筆耕文化傳播整理發(fā)布。
一、改善代碼的三部曲
《設(shè)計(jì)模式》-> 《重構(gòu)》-> 《重構(gòu)與模式》。也就是設(shè)計(jì)->重構(gòu)->重構(gòu)出新設(shè)計(jì)。
《設(shè)計(jì)模式》主要詳細(xì)說(shuō)明20幾種模式,為我們帶來(lái)了常見(jiàn)設(shè)計(jì)問(wèn)題的經(jīng)典解決方案,從而改變了整個(gè)面向?qū)ο箝_(kāi)發(fā)的面貌。為設(shè)計(jì)而著。
《重構(gòu)》改善既有代碼的設(shè)計(jì),總結(jié)了我們會(huì)用到的各種重構(gòu)手法,為我們帶來(lái)了一種改進(jìn)代碼的高效過(guò)程,從而徹底改變了面向?qū)ο笤O(shè)計(jì)的方式。側(cè)重去除壞代碼的味道。
《重構(gòu)與模式》是設(shè)計(jì)模式相關(guān)的重構(gòu)。模式不是設(shè)計(jì)出來(lái)的,是重構(gòu)出來(lái)的。好的設(shè)計(jì)也不是設(shè)計(jì)出來(lái)的,是重構(gòu)出來(lái)的。不要怕改變,只要改變得法,變就不再是災(zāi)難,而是進(jìn)步的良機(jī)。側(cè)重設(shè)計(jì)模式+重構(gòu)手段。
在閱讀重構(gòu)與模式之前,最好熟讀前面兩本:《設(shè)計(jì)模式》和《重構(gòu)》。
設(shè)計(jì)模式代表了傳統(tǒng)的軟件開(kāi)發(fā)思想:好的設(shè)計(jì)會(huì)產(chǎn)生好的軟件,因此在實(shí)際開(kāi)發(fā)之前,值得花時(shí)間去做一個(gè)全面而細(xì)致的設(shè)計(jì)。重構(gòu)代表了敏捷軟件開(kāi)發(fā)的浪潮:軟件并不是在一開(kāi)始就可以設(shè)計(jì)得完美無(wú)缺的,因此可以先進(jìn)行實(shí)際開(kāi)發(fā),然后通過(guò)對(duì)代碼不斷的進(jìn)行小幅度的修改來(lái)改善其設(shè)計(jì)。二者從不同角度闡述了設(shè)計(jì)的重要性。
有些人在編寫(xiě)任何代碼之前,都要很早地為模式做計(jì)劃,而有些人在編寫(xiě)了大量代碼之后才開(kāi)始添加模式。
第二種使用模式的方式就是重構(gòu),因?yàn)槭且诓辉黾酉到y(tǒng)特性或者不改變其外部行為的情況下改變系統(tǒng)的設(shè)計(jì)。
有些人在程序中加入模式,只是因?yàn)橛X(jué)得模式能夠使程序更容易修改;更多人這樣做只是為了簡(jiǎn)化目前的設(shè)計(jì)。
如果代碼已經(jīng)編寫(xiě),這兩種情形都是重構(gòu),因?yàn)榍罢呤峭ㄟ^(guò)重構(gòu)使修改更容易,而后者則是通過(guò)重構(gòu)在修改后進(jìn)行整理。
雖然模式是在程序中能夠看到的東西,但是模式也是一種程序轉(zhuǎn)換。
重構(gòu)是實(shí)現(xiàn)設(shè)計(jì)模式的一種手段,設(shè)計(jì)模式往往也是重構(gòu)的目的。
二、重構(gòu)與模式的緣由
應(yīng)該通過(guò)重構(gòu)實(shí)現(xiàn)模式、趨向模式和去除模式(refactoring to, towards, and away from pattern),而不是在預(yù)先設(shè)計(jì)中使用模式,也不再過(guò)早的在代碼中加入模式。這技能避免過(guò)度設(shè)計(jì),又不至于設(shè)計(jì)不足。
但是后來(lái)卻沒(méi)怎么動(dòng),也就是導(dǎo)致了廢設(shè)計(jì)和功能.
2.設(shè)計(jì)不足
產(chǎn)生設(shè)計(jì)不足的原因:
1)程序員沒(méi)有時(shí)間,沒(méi)有抽出時(shí)間,或者時(shí)間不允許進(jìn)行重構(gòu)
2)程序員在何為好的軟件設(shè)計(jì)方面知識(shí)不足
3)程序員被要求在既有系統(tǒng)中快速的添加新功能
4)程序員被迫同時(shí)進(jìn)行太多項(xiàng)目
長(zhǎng)期的設(shè)計(jì)不足,會(huì)使軟件開(kāi)發(fā)節(jié)奏變成“快,慢,更慢”,可能的后果是:
1.0版本很快就交付了,但是代碼質(zhì)量很差
2.0版本也交付了,但質(zhì)量低劣的代碼使我們慢下來(lái)
在企圖交付未來(lái)版本時(shí),隨著劣質(zhì)代碼的倍增,開(kāi)發(fā)速度也越來(lái)越慢,最后人們對(duì)系統(tǒng)、程序員乃至使大家陷入這種境地的整個(gè)過(guò)程都失去了信心
到了4.0版本時(shí)或者之后,我們意識(shí)到這樣肯定不行,開(kāi)始考慮推倒重來(lái)
3.測(cè)試驅(qū)動(dòng)開(kāi)發(fā)和持續(xù)重構(gòu),
測(cè)試驅(qū)動(dòng)開(kāi)發(fā)和持續(xù)重構(gòu)提供了一種精益、迭代和訓(xùn)練有素的編程風(fēng)格,能夠最大程度的有張有弛,提高生產(chǎn)率!把杆俣謴娜莶黄取
使用測(cè)試驅(qū)動(dòng)開(kāi)發(fā)和持續(xù)重構(gòu)的益處:
1)保持較低的缺陷數(shù)量
2)大膽的進(jìn)行重構(gòu)
3)得到更加簡(jiǎn)單、更加優(yōu)秀的代碼
4)編程時(shí)沒(méi)有壓力
模式和重構(gòu)之間存在著天然聯(lián)系,模式是你想達(dá)到的目的地,而重構(gòu)則是從其他地方抵達(dá)這個(gè)目的地的條條道路。
4.演進(jìn)式設(shè)計(jì)
演進(jìn)式設(shè)計(jì)即趨向性設(shè)計(jì),主要是避免過(guò)度設(shè)計(jì)。
通過(guò)重構(gòu)產(chǎn)生設(shè)計(jì)結(jié)構(gòu),也就是通過(guò)重構(gòu)實(shí)現(xiàn)模式或者重構(gòu)趨向模式。為設(shè)計(jì)而設(shè)計(jì)的思路并不適合大項(xiàng)目,循序漸進(jìn)從重構(gòu)到設(shè)計(jì)模式才是設(shè)計(jì)模式的王道。
敏捷開(kāi)發(fā)中經(jīng)常采用的演進(jìn)式架構(gòu)設(shè)計(jì):
很多程序員可能都遇見(jiàn)過(guò)這種事:某塊代碼亟待修改,卻沒(méi)有人愿意接手。為什么會(huì)這樣?這段代碼正巧是兩個(gè)組件間的接口,修改工作太過(guò)困難。而在演進(jìn)式設(shè)計(jì)中,我們常常會(huì)做這種修改。代碼應(yīng)當(dāng)是"活的"并且是"可生長(zhǎng)"的,決不能無(wú)視強(qiáng)烈的變化需求 而保持一成不變。正因?yàn)槿绱耍?span>演進(jìn)式設(shè)計(jì)可以提高設(shè)計(jì)質(zhì)量,進(jìn)而提高整個(gè)系統(tǒng)的質(zhì)量。
第6章創(chuàng)建
6.1 用Creating Method替換構(gòu)造函數(shù)
當(dāng)類中有多個(gè)構(gòu)造函數(shù),因此很難決定在開(kāi)發(fā)期間用哪一個(gè)時(shí),可以用能夠說(shuō)明意圖的返回對(duì)象實(shí)例的Creation Method替換構(gòu)造函數(shù)
動(dòng)機(jī):
Creation Method——類中的一個(gè)靜態(tài)或者非靜態(tài)的負(fù)責(zé)實(shí)例化類的新實(shí)例方法。因Creating Method命名沒(méi)有限制,所以可以取最能表達(dá)所創(chuàng)建對(duì)象的名字。
類中有太多構(gòu)造函數(shù)→提煉類或者提煉子類 或者 用Creation Method替換構(gòu)造函數(shù)來(lái)澄清構(gòu)造函數(shù)的意圖
優(yōu)缺點(diǎn):
+ 比構(gòu)造函數(shù)能夠更好的表達(dá)所創(chuàng)建的實(shí)例種類
+ 避免了構(gòu)造函數(shù)的局限,比如兩個(gè)構(gòu)造函數(shù)的參數(shù)數(shù)目和類型不能相同
+ 更容易發(fā)現(xiàn)無(wú)用的創(chuàng)建代碼
- 創(chuàng)建方式是非標(biāo)準(zhǔn)的,有的用new實(shí)例化,而有的用Creation Method實(shí)例化
變體:
不需要為每個(gè)對(duì)象的配置都設(shè)立一個(gè)Creation Method,非必要情況下可以添加參數(shù)來(lái)減少Creation Method的數(shù)量
當(dāng)Creation Method過(guò)多的分散了類的主要職責(zé)是,應(yīng)該考慮將相關(guān)的Creation Method重構(gòu)為一個(gè)Factory
6.2 將創(chuàng)建知識(shí)搬移到Factory
當(dāng)用來(lái)實(shí)例化一個(gè)類的數(shù)據(jù)和代碼在多個(gè)類中到處都是時(shí),可以講有關(guān)創(chuàng)建的知識(shí)搬移到一個(gè)Factory中
動(dòng)機(jī):
創(chuàng)建蔓延——將創(chuàng)建的職責(zé)放在了不應(yīng)該承擔(dān)對(duì)象創(chuàng)建任務(wù)的類中,,是解決方案蔓延中的一種,一般是之前的設(shè)計(jì)問(wèn)題導(dǎo)致。
使用一個(gè)Factory類封裝創(chuàng)建邏輯和客戶代碼的實(shí)例化選項(xiàng),客戶可以告訴Factory實(shí)例如何實(shí)例化一個(gè)對(duì)象,然后用同一個(gè)Factory實(shí)例在運(yùn)行時(shí)執(zhí)行實(shí)例化。
Factory不需要用具體類專門實(shí)現(xiàn),可以使用一個(gè)接口定義Factory,然后讓現(xiàn)有的類實(shí)現(xiàn)這個(gè)接口。
如果Factory中創(chuàng)建邏輯過(guò)于復(fù)雜,應(yīng)將其重構(gòu)為Abstract Factory,客戶代碼可以配置系統(tǒng)使用某個(gè)ConcreteFactory(AbstractFactory的一個(gè)具體實(shí)現(xiàn))或者默認(rèn)的ConcreteFactory。
只有確實(shí)改進(jìn)了代碼設(shè)計(jì),或者無(wú)法直接進(jìn)行實(shí)例化時(shí)才有足夠的理由進(jìn)行Factory重構(gòu)
優(yōu)缺點(diǎn):
+ 合并創(chuàng)建邏輯和實(shí)例化選項(xiàng)
+ 將客戶代碼與創(chuàng)建邏輯解耦
- 如果可以直接實(shí)例化,會(huì)使設(shè)計(jì)復(fù)雜化
6.3 用Factory封裝類
當(dāng)直接實(shí)例化處在同一包結(jié)構(gòu)中、實(shí)現(xiàn)統(tǒng)一接口的多個(gè)類?梢园杨惖臉(gòu)造函數(shù)聲明為非公共的,并通過(guò)Factory來(lái)創(chuàng)建它們的實(shí)例
動(dòng)機(jī):
可以通過(guò)Factory將一組客戶并不需關(guān)心的子類屏蔽到包內(nèi)部。
如果類共享一個(gè)通用的公共接口、共享相同的超類、并且處在同一包結(jié)構(gòu)中,該重構(gòu)可能有用。
優(yōu)缺點(diǎn):
+ 通過(guò)意圖導(dǎo)向的Creation Method簡(jiǎn)化了不同種類實(shí)例的創(chuàng)建
+ 通過(guò)隱藏不需要公開(kāi)的類減少了包的“概念重量”
+ 幫助嚴(yán)格執(zhí)行“面向接口編程,而不是面向?qū)崿F(xiàn)”這一格言
- 當(dāng)需要?jiǎng)?chuàng)建新種類的實(shí)例時(shí),必須更新Creation Method
- 當(dāng)客戶只能獲得Factory的二進(jìn)制代碼而無(wú)法獲得源碼時(shí),對(duì)Factory的定制將受到限制
6.4 用Factory Method引入多態(tài)創(chuàng)建
當(dāng)一個(gè)層次中的類都相似的實(shí)現(xiàn)一個(gè)方法,只是對(duì)象創(chuàng)建的步驟不同時(shí),可以創(chuàng)建調(diào)用Factory Method來(lái)處理實(shí)例化方法的唯一超類版本
動(dòng)機(jī):
Factory Method是OOP中最常見(jiàn)的模式,因其提供了多臺(tái)創(chuàng)建對(duì)象的方法
使用Factory Method后的代碼往往比在類中賦值方法來(lái)創(chuàng)建自定義對(duì)象要簡(jiǎn)單
使用Factory Method的主要情況:
當(dāng)兄弟子類實(shí)現(xiàn)了除對(duì)象創(chuàng)建步驟外都很相似的方法時(shí)
當(dāng)超類和子類實(shí)現(xiàn)了除對(duì)象創(chuàng)建步驟外都很相似的方法時(shí)
優(yōu)缺點(diǎn):
+ 減少因創(chuàng)建自定義對(duì)象而產(chǎn)生的重復(fù)代碼
+ 有效的表達(dá)了對(duì)象創(chuàng)建發(fā)生的位置,以及如何重寫(xiě)對(duì)象的創(chuàng)建
+ 強(qiáng)制Factory Method使用的類必須實(shí)現(xiàn)統(tǒng)一的類型
- 可能會(huì)向Factory Method的一些實(shí)現(xiàn)者傳遞不必要的參數(shù)
6.5 用Builder封裝Composite
當(dāng)構(gòu)造Composite是重復(fù)的、復(fù)雜的且容易出錯(cuò)的工作時(shí),通過(guò)使用Builder處理構(gòu)造細(xì)節(jié)來(lái)簡(jiǎn)化構(gòu)造過(guò)程。
動(dòng)機(jī):
構(gòu)造Composite是重復(fù)的、復(fù)雜的、容易出錯(cuò)的工作,通過(guò)使用Builder處理構(gòu)造細(xì)節(jié)來(lái)簡(jiǎn)化構(gòu)造過(guò)程
Builder模式很擅長(zhǎng)處理繁重的、復(fù)雜的構(gòu)造步驟。
Builder模式的意圖:將一個(gè)復(fù)雜對(duì)象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過(guò)程可以創(chuàng)建不同的表示。
優(yōu)缺點(diǎn):
+ 簡(jiǎn)化了構(gòu)造Composite的客戶代碼
+ 減少了創(chuàng)建Composite的重復(fù)和易出錯(cuò)的本性
+ 在客戶代碼和Composite之間實(shí)現(xiàn)了松耦合
+ 允許對(duì)已封裝的Composite或復(fù)雜對(duì)象創(chuàng)建不同的表示
- 接口可能不會(huì)很清楚的表達(dá)其意圖
6.6 內(nèi)聯(lián)Singleton
當(dāng)代碼需要訪問(wèn)一個(gè)對(duì)象,但是不需要對(duì)象的全局入口時(shí),可以把Singleton的功能搬移到一個(gè)保存并提供對(duì)象訪問(wèn)入口的類中。刪除Singleton。
動(dòng)機(jī):
Singleton意圖:確保一個(gè)類僅有一個(gè)實(shí)例,并提供一個(gè)訪問(wèn)它的全局訪問(wèn)點(diǎn)
保持暴露對(duì)象和保護(hù)對(duì)象之間的平衡對(duì)維護(hù)系統(tǒng)的靈活性是至關(guān)重要的
任何全局?jǐn)?shù)據(jù)在被證明是無(wú)害之前都是有害的
如果遇到本不該實(shí)現(xiàn)為Singleton的Singleton,不要猶豫,內(nèi)聯(lián)它!
優(yōu)缺點(diǎn):
+ 使對(duì)象的協(xié)作變得更明顯和明確
+ 保護(hù)了單一的實(shí)例,且不需要特殊的代碼
- 當(dāng)在許多層次間傳遞對(duì)象實(shí)例比較困難的時(shí)候,會(huì)使設(shè)計(jì)變得復(fù)雜
第7章 簡(jiǎn)化
我們所編寫(xiě)的絕大部分代碼都不會(huì)從一開(kāi)始就很簡(jiǎn)單。
算法經(jīng)常會(huì)因?yàn)橹С侄喾N變化而變得復(fù)雜。
控制狀態(tài)轉(zhuǎn)換的轉(zhuǎn)換的邏輯往往會(huì)變得越來(lái)越復(fù)雜。
7.1 組合方法
當(dāng)你無(wú)法迅速的理解一個(gè)方法的邏輯時(shí),把方法的邏輯轉(zhuǎn)換成幾個(gè)同一層面上的、能夠說(shuō)明意圖的步驟。
動(dòng)機(jī):
Composed Method由對(duì)其他方法的調(diào)用組成,好的Composed Method的代碼都在細(xì)節(jié)的同一層面上。
Composed Method一般不會(huì)引入性能問(wèn)題
優(yōu)缺點(diǎn):
+ 清晰的描述了一個(gè)方法所實(shí)現(xiàn)的功能以及如何實(shí)現(xiàn)
+ 把方法分解成命名良好的、處在細(xì)節(jié)的同一層面上的行為模塊,以此來(lái)簡(jiǎn)化方法
- 可能會(huì)產(chǎn)生過(guò)多的小方法
- 可能會(huì)使調(diào)試變得困難,因?yàn)槌绦虻倪壿嫹稚⒃谠S多小方法中
Composed Method指導(dǎo)原則:
Composed Method都很小。一般在5行左右,很少超過(guò)10行
刪除重復(fù)代碼和死代碼。除去明顯的和微妙的代碼重復(fù),除去沒(méi)有被使用的代碼,以減少方法的代碼量
表達(dá)意圖。清楚的命名程序中的變量、方法和參數(shù),使它們明確表達(dá)意圖。
簡(jiǎn)化。轉(zhuǎn)換代碼,使它盡可能簡(jiǎn)單。
使用細(xì)節(jié)的統(tǒng)一層面。當(dāng)把一個(gè)方法分解成一組行為時(shí),要保證這些行為在細(xì)節(jié)的相似層面上。
7.2 用Strategy替換條件邏輯
當(dāng)方法中條件邏輯控制著應(yīng)該執(zhí)行計(jì)算的哪個(gè)變體時(shí),為每個(gè)變體創(chuàng)建一個(gè)Strategy并使方法把計(jì)算委托到Strategy實(shí)例。
動(dòng)機(jī):
——為算法的各個(gè)變體生成一系列的類,并用Strategy的一個(gè)實(shí)例裝配主類,主類在運(yùn)行時(shí)委托到該Strategy實(shí)例
復(fù)雜的條件邏輯是最常導(dǎo)致復(fù)雜度上升的地點(diǎn)之一
優(yōu)缺點(diǎn):
+ 通過(guò)減少或去除條件邏輯使算法變得清晰易懂
+ 通過(guò)把算法的變體搬移到類層次中簡(jiǎn)化了類
+ 允許在運(yùn)行時(shí)用一種算法替換另一種算法
- 當(dāng)應(yīng)用基于繼承的解決方案或“簡(jiǎn)化條件表達(dá)式”中的重構(gòu)更簡(jiǎn)單時(shí),會(huì)增加設(shè)計(jì)的復(fù)雜度
- 增加了算法如何獲取或接收上下文類數(shù)據(jù)的復(fù)雜度
7.3 將裝飾功能搬移到Decorator
當(dāng)代碼向類和核心職責(zé)提供裝飾功能時(shí),可以考慮將裝飾代碼搬移到Decorator
無(wú)論多么喜歡一個(gè)模式,不要在不必要的時(shí)候使用它
優(yōu)缺點(diǎn):
+ 把裝飾功能從類中移除,從而簡(jiǎn)化類
+ 有效的把類的核心職責(zé)和裝飾功能區(qū)分開(kāi)來(lái)
+ 可以去除幾個(gè)相關(guān)類中重復(fù)的裝飾邏輯
- 改變了被裝飾對(duì)象的類型
- 會(huì)使代碼變得更難理解和調(diào)試
- 當(dāng)Decorator組合產(chǎn)生負(fù)面影響的時(shí)候,會(huì)增加設(shè)計(jì)的復(fù)雜度
7.4 用State替換狀態(tài)改變條件語(yǔ)句
當(dāng)控制一個(gè)對(duì)象狀態(tài)轉(zhuǎn)換的條件表達(dá)式過(guò)于復(fù)雜時(shí),可以考慮用處理特殊狀態(tài)轉(zhuǎn)換的State類替換條件語(yǔ)句
優(yōu)缺點(diǎn):
+ 減少或去除狀態(tài)改變條件邏輯
+ 簡(jiǎn)化了復(fù)雜的狀態(tài)改變邏輯
+ 提供了觀察狀態(tài)改變邏輯的很好的鳥(niǎo)瞰圖
- 當(dāng)狀態(tài)轉(zhuǎn)換邏輯已經(jīng)易于理解的時(shí)候,會(huì)增加設(shè)計(jì)的復(fù)雜度
7.5 用Composite替換隱含樹(shù)
當(dāng)用原生表示法隱含的形成了樹(shù)結(jié)構(gòu)時(shí),可以考慮用Composite替換這個(gè)原生表示法
優(yōu)缺點(diǎn):
+ 封裝重復(fù)的指令,如格式化、添加或刪除結(jié)點(diǎn)
+ 提供了處理相似邏輯增長(zhǎng)的一般性方法
+ 簡(jiǎn)化了客戶代碼的構(gòu)造職責(zé)
- 當(dāng)構(gòu)造隱式樹(shù)更簡(jiǎn)單的時(shí)候,會(huì)增加設(shè)計(jì)的復(fù)雜度
7.6 用Command替換條件調(diào)度程序
當(dāng)條件邏輯用來(lái)調(diào)度請(qǐng)求和執(zhí)行操作時(shí),為每個(gè)動(dòng)作創(chuàng)建一個(gè)Command。把這些Command存儲(chǔ)在一個(gè)集合中,并用獲取及執(zhí)行Command的代碼替換條件邏輯。
為每個(gè)動(dòng)作創(chuàng)建一個(gè)Command,把這些Command存儲(chǔ)在一個(gè)集合中,并用獲取及執(zhí)行Command的代碼替換條件邏輯
優(yōu)缺點(diǎn):
+ 提供了用統(tǒng)一方法執(zhí)行不同行為的簡(jiǎn)單機(jī)制
+ 允許在運(yùn)行時(shí)改變所處理的請(qǐng)求,以及如何處理請(qǐng)求
+ 僅僅需要很少的代碼實(shí)現(xiàn)
- 當(dāng)條件調(diào)度程序已經(jīng)足夠的時(shí)候,會(huì)增加設(shè)計(jì)的復(fù)雜度
第8章 泛化
泛化是把特殊代碼轉(zhuǎn)換成通用目的代碼的過(guò)程。泛化代碼的產(chǎn)生往往的重構(gòu)的結(jié)果。
8.1 形成Template Method
當(dāng)子類中的兩個(gè)方法以相同的順序執(zhí)行相似的步驟,但是步驟并不完全相同。通過(guò)把這些步驟提取成具有相同簽名的方法來(lái)泛化這兩個(gè)方法,然后上移這些泛化方法,形成Template Method。
優(yōu)缺點(diǎn):
+ 通過(guò)把不變行為搬移到超類,去除子類中的重復(fù)代碼
+ 簡(jiǎn)化并有效的表達(dá)了一個(gè)通用算法的步驟
+ 允許子類很容易的定制一個(gè)算法
- 當(dāng)為了生成算法,子類必須實(shí)現(xiàn)很多方法的時(shí)候,會(huì)增加設(shè)計(jì)的復(fù)雜度
8.2 提取Composite
當(dāng)一個(gè)類層次結(jié)構(gòu)中的多個(gè)子類實(shí)現(xiàn)了同一個(gè)Composite時(shí),可以提取一個(gè)實(shí)現(xiàn)該Composite的超類
優(yōu)缺點(diǎn):
+ 去除重復(fù)的類存儲(chǔ)邏輯和類處理邏輯
+ 能夠有效的表達(dá)類處理邏輯的可繼承性
8.3 用Composite替換一/多之分
當(dāng)類使用不同的代碼處理單一對(duì)象與多個(gè)對(duì)象時(shí),用Composite能夠產(chǎn)生既可以處理單一對(duì)象又可以處理多個(gè)對(duì)象的代碼
優(yōu)缺點(diǎn):
+ 去除與處理一個(gè)或多個(gè)對(duì)象相關(guān)聯(lián)的重復(fù)代碼
+ 提供處理一個(gè)或多個(gè)對(duì)象的統(tǒng)一方法
+ 支持處理多個(gè)對(duì)象的更豐富的方法
- 可能會(huì)在Composite的構(gòu)造過(guò)程中要求類型安全的運(yùn)行時(shí)檢查
8.4 用Observer替換硬編碼的通知
當(dāng)子類通過(guò)硬編碼來(lái)通知另一個(gè)類的實(shí)例時(shí)可以去除這些子類,并使其超類能夠通知一個(gè)或多個(gè)實(shí)現(xiàn)了Observer接口的類
優(yōu)缺點(diǎn):
+ 使主題及其觀察者訪問(wèn)松散耦合
+ 支持一個(gè)或多個(gè)觀察者
- 當(dāng)硬編碼的通知已經(jīng)足夠的時(shí)候,會(huì)增加設(shè)計(jì)的復(fù)雜度
- 當(dāng)出現(xiàn)串聯(lián)通知的時(shí)候,會(huì)增加代碼的復(fù)雜度
- 當(dāng)觀察者沒(méi)有從它們的主題中被刪除的時(shí)候,可能會(huì)造成資源泄漏
8.5 通過(guò)Adapter統(tǒng)一接口
當(dāng)客戶代碼與兩個(gè)類交互,其中的一個(gè)類具有首選接口,可以用一個(gè)Adapter統(tǒng)一接口
動(dòng)機(jī):
當(dāng)下面條件都為真時(shí),重構(gòu)Adapter就是有用的:
兩個(gè)類所做的事情相同或相似,但是具有不同的接口
如果類共享同一個(gè)接口,客戶代碼會(huì)更簡(jiǎn)單、更直接、更緊湊
無(wú)法輕易改變其中一個(gè)類的接口,因?yàn)樗堑谌綆?kù)中的一部分,或者它是一個(gè)已經(jīng)被其他客戶代碼廣泛使用的框架的一部分,或者無(wú)法獲得源碼
優(yōu)缺點(diǎn):
+ 使客戶代碼可以通過(guò)相同的接口與不同的類交互,從而去除或減少重復(fù)代碼
+ 使客戶代碼可以通過(guò)公共的接口與多個(gè)對(duì)象交互,從而簡(jiǎn)化了客戶代碼
+ 統(tǒng)一了客戶代碼與不同類的交互方式
- 當(dāng)類的接口可以改變的時(shí)候,會(huì)增加設(shè)計(jì)的復(fù)雜度
8.6 提取Adapter
當(dāng)一個(gè)類適配了多個(gè)版本的組件、類庫(kù)、API或其他實(shí)體時(shí),可以為組件、類庫(kù)、API或其他實(shí)體的每個(gè)版本提取一個(gè)Adapter
Adapter用來(lái)適配對(duì)象,F(xiàn)acade用來(lái)適配整個(gè)系統(tǒng),F(xiàn)acade通常用來(lái)與遺留系統(tǒng)進(jìn)行交互
優(yōu)缺點(diǎn):
+ 隔離了不同版本的組件、類庫(kù)或API之間的不同之處
+ 使類只負(fù)責(zé)適配代碼的一個(gè)版本
+ 避免頻繁的修改代碼
- 如果某個(gè)重要行為在Adapter中不可用的話,那么客戶代碼將無(wú)法執(zhí)行這一重要行為
8.7 用Interpreter替換隱式語(yǔ)言
當(dāng)類中的許多方法組合成了一種隱式語(yǔ)言的元素,可以為隱式語(yǔ)言的元素定義類,這樣就可以通過(guò)類實(shí)例組合,形成易于理解的表達(dá)式
優(yōu)缺點(diǎn):
+ 比隱式語(yǔ)言更好的支持語(yǔ)言元素的組合
+ 不需要解析新的代碼來(lái)支持語(yǔ)言元素的新組合
+ 允許行為的運(yùn)行時(shí)配置
- 會(huì)產(chǎn)生定義語(yǔ)言和修改客戶代碼的開(kāi)銷
- 如果語(yǔ)言很復(fù)雜,則需要很多的編程工作
- 如果語(yǔ)言本身就很簡(jiǎn)單,則會(huì)增加設(shè)計(jì)的復(fù)雜度
第9章 保護(hù)
9.1 用類替換類型代碼
字段的類型無(wú)法保護(hù)它免受不正確的復(fù)制和非法的等同性比較,可以把字段的類型聲明為類,從而限制復(fù)制和等同性比較
優(yōu)缺點(diǎn):
+ 更好的避免非法賦值和比較
- 比使用不安全類型要求更多的代碼
9.2 用Singleton限制實(shí)例化
代碼創(chuàng)建了一個(gè)對(duì)象的多個(gè)實(shí)例,并導(dǎo)致內(nèi)存使用過(guò)多和系統(tǒng)性能下降時(shí),可以用Singleton替換多個(gè)實(shí)例
不要做不成熟的代碼優(yōu)化,經(jīng)過(guò)不成熟優(yōu)化的代碼比未優(yōu)化的代碼更難于重構(gòu)。在代碼優(yōu)化之前,你會(huì)發(fā)現(xiàn)更多可以改進(jìn)的地方
優(yōu)缺點(diǎn):
+ 改進(jìn)性能
- 在任何地方都可以很容易的訪問(wèn)。在很多情況下,這可能是設(shè)計(jì)的缺點(diǎn)
- 當(dāng)對(duì)象含有不能共享的狀態(tài)時(shí),本重構(gòu)無(wú)效
9.3 引入Null Object
當(dāng)代碼中到處都是處理null字段或變量的重復(fù)邏輯時(shí),將null邏輯替換為一個(gè)Null Object,一個(gè)提供正確null行為的對(duì)象
優(yōu)缺點(diǎn):
+ 不需要重復(fù)的null邏輯就可以避免null錯(cuò)誤
+ 通過(guò)最小化null測(cè)試簡(jiǎn)化了代碼
- 當(dāng)系統(tǒng)不太需要null測(cè)試的時(shí)候,會(huì)增加設(shè)計(jì)的復(fù)雜度
- 如果程序員不知道Null Object的存在,就會(huì)產(chǎn)生多余的null測(cè)試
- 使維護(hù)變得復(fù)雜,擁有超類的Null Object必須重寫(xiě)所有新繼承到的公共方法
第10章 聚集操作
10.1 將聚集操作搬移到Collecting Parameter
有一個(gè)很大的方法將信息聚集到一個(gè)局部變量中時(shí),可以把結(jié)果聚集到一個(gè)Collecting Parameter中,并將它傳入被提煉出的方法中
優(yōu)缺點(diǎn):
+ 幫助我們把很大的方法轉(zhuǎn)換成更小的,更簡(jiǎn)單的多個(gè)方法
- 使結(jié)果代碼運(yùn)行得更快
10.2 將聚集操作搬移到Visitor
有一個(gè)方法從不同的類中聚集信息,可以把聚集工作搬移到一個(gè)能夠訪問(wèn)每個(gè)類以便采集信息的Visitor中。
優(yōu)缺點(diǎn):
+ 調(diào)節(jié)多個(gè)算法,使其適用于不同的對(duì)象結(jié)構(gòu)
+ 訪問(wèn)相同或不同繼承結(jié)構(gòu)中的類
+ 調(diào)用不同類上的類型特定方法,無(wú)需類型轉(zhuǎn)換
- 當(dāng)可以使用通用接口把互不相同的類變成相似類的時(shí)候,會(huì)增加代碼的復(fù)雜度
- 新的可訪問(wèn)類需要新的接收方法,每個(gè)Visitor中需要新的訪問(wèn)方法
- 可能會(huì)破壞訪問(wèn)類的封裝性
第11章 使用重構(gòu)
11.1 鏈構(gòu)造函數(shù)
有很多包含重復(fù)代碼的構(gòu)造函數(shù)時(shí),可以把構(gòu)造函數(shù)鏈接起來(lái),從而獲得最少的代碼重復(fù)。
11.2 統(tǒng)一接口
當(dāng)需要一個(gè)與其子類具有相同接口的超類或接口時(shí),可以找到所有子類含有而超類沒(méi)有的公共方法,把這些方法復(fù)制到超類中,并修改每個(gè)方法,使其執(zhí)行空行為。
11.3 提取參數(shù)
當(dāng)一個(gè)方法或構(gòu)造函數(shù)將一個(gè)字段賦值為一個(gè)局部實(shí)例化的值時(shí),可以把賦值聲明的右側(cè)提取到一個(gè)參數(shù)中,并通過(guò)客戶代碼提供的參數(shù)對(duì)字段進(jìn)行賦值。
本文關(guān)鍵詞:重構(gòu)與模式,由筆耕文化傳播整理發(fā)布。
本文編號(hào):73368
本文鏈接:http://sikaile.net/wenshubaike/mishujinen/73368.html