學習基礎:熟悉《設計模式》和《重構》的概念,熟悉基本的Java語法和XML語法,熟悉Eclipse和JUnit的使用,有相對較好的英語基礎。程序員
學習過程:算法
先按P40的學習順序讀完序號1~9。理解每一個重構模式的動機,嘗試讀懂示例中的代碼(實在不懂就放過,找機會上機也能明白)。數據庫
在時間容許的條件下,能夠重讀和對書中代碼重構,從而更加充分地理解重構與模式這兩個重要的概念和實踐方法。編程
學習目的:使本身編寫的代碼更容易被人讀懂。設計模式
學習感悟:安全
代碼的重構應該是一步步完成的,每次重構的部分不要超過本身的理解能力的5%。雖然這樣操做略顯繁瑣,可是能夠減輕頭腦重構過程當中的記憶強度,減小代碼出錯的機會。函數
代碼的重構必定要配合JUnit(TDD,測試驅動開發)完成,再加上Git(版本管理)和Eclipse(IDE的重構工具)那就事半功倍了。工具
6.1. (P43)用Creation Method替換構造函數:用明確的建立方法代替類中的多個構造函數,避免建立新類時客戶沒法正確理解和使用構造函數的意圖。性能
優勢與缺點:學習
+ 相比構造函數可以更好地表達所建立的實例的意圖;
+ 避免了構造函數的侷限性,例如:兩個構造函數不能經過相同的參數和不一樣的返回類型進行重載;
+ 更容易發現無用的建立代碼;
- 非標準化的建立方式,例如:不是統一用new的方式實例化。
11.1.(P275) 構造函數鏈:把構造函數連接起來,減小代碼的重複。特殊的構造函數調用更通用的構造函數,直到全包含構造函數(處理全部的構造函數調用)。
當構造函數數量過多時,可使用Creation Method(6.1節)重構。
6.3. (P60)用Factory封裝類:將同一個包裏面、實現了相同接口的多個類的實例化交由工廠完成。
優勢與缺點:
+ 經過Creation Method簡化不一樣種類實例的建立;
+ 經過隱藏類減小包結構的「概念重量」;
+ 經過共享公共接口實踐「面向接口編程,而不要面向實現編程」的理念;
- 增長新的種類的實例時,必須修改或者增長新的Creation Method;
- 當客戶只能得到Factory的二進制代碼而不是源代碼時,對Factory的制定將受到限制。
6.4. (P67)用Factory Method引入多態建立:將一樣的超類,不一樣的建立過程統一交由工廠完成。
優勢與缺點:
+ 減小因建立自定義對象而產生的重複代碼;
+ 有效地表達了對象建立發生的位置,以及如何重寫對象的建立;
+ 強制Factory Method使用的類必須實現統一的接口;
- 可能會向Factory Method的一些實現者傳遞沒必要要的參數。
7.2.(P102) 用Strategy替換條件邏輯
優勢與缺點:
+ 經過減小或者去除條件邏輯使算法變得清晰易懂;
+ 經過把算法的變體搬移到類層次中簡化了類;
+ 容許在運行時用一種算法替換另外一種算法;
- 增長設計的複雜度;
- 增長了算法獲取數據的複雜度。
8.1. (P166)造成Template Method:經過將不一樣方法中相同的順序執行步驟提取出來從而實現泛化。
優勢與缺點:
+ 經過把不變行爲搬移到超類,去除子類中的重複代碼;
+ 簡化並有效地表達了一個通用算法的步驟;
+ 容許子類很容易地定製一個算法;
- 當爲了生成算法致使子類必須實現不少方法的時候,就增長了設計的複雜度。
XMLBuilder的例子依據的有(7.5)TagNode,(6.5)TagBuilder,(10.1)TagNode,代碼中存在一些小問題,能夠試着本身修改。
7.1. (P97)Composed Method(組合方法)模式:將代碼組合成名字簡單易懂的方法,再將這些方法組合成更大的方法,從而方便讀懂代碼。
優勢與缺點:
+ 清晰地描述了一個方法所實現的功能以及如何實現;
+ 把方法分解成命名良好的、處在細節的同一層面上的行爲模塊,以此來簡化方法;
- 可能會產生過多的小方法;
- 可能會使調試變得困難,由於程序的邏輯分散在許多小方法中。
7.5. (P143)Composite模式:隱式地構造出樹形結構。
優勢與缺點:
+ 封裝重複的指令,如格式化、添加或刪除結點;
+ 提供了處理類似邏輯增加的通常性方法;
+ 簡化了客戶代碼的構造職責;
- 構造的隱式的樹結構越簡單,設計的時候就越複雜。
6.5. (P74)用Builder封裝Composite:由於構造Composite有許多重複工做,而且工做流程是複雜並且容易出錯的,經過Builder來處理構造細節來簡化構造過程。
優勢與缺點:
+ 簡化了構造Composite的客戶代碼;
+ 減小了建立Composite的重複和易出錯的問題;
+ 在客戶代碼和Composite之間實現了鬆耦合;
+ 容許對已經封裝的Composite或複雜的對象建立不一樣的表示;
- 接口可能沒法清楚地表達其本質意圖。
10.1. Collecing Parameter(彙集參數)模式:是把一個對象傳入到不一樣的方法中,從而在這些方法中收集信息。
常常與Composed Method模式一塊兒使用。
優勢與缺點:
+ 能夠把很大的方法轉換成更上的、更簡單的方法;
- 少許地影響結果代碼的運行速度。
8.2.(P172) 提取Composite:將同一個超類下的多個子類實現的一樣的Composite提取到超類中。
優勢與缺點:
+ 去除重複的類存儲邏輯和類處理邏輯;
+ 可以有效地表達類處理邏輯的可繼承性。
8.3.(P180) 用Composite替換一個對象和多個對象的分別:用Composite實現了既能夠處理一個對象,也能夠處理多個對象的一樣的函數接口。
優勢與缺點:
+ 去除了處理一個對象的方法和多個對象的方法中重複的代碼;
+ 提供了處理一個對象和多個對象的統一函數方法;
+ 提供了處理多個對象的更豐富的方法(例如:OR表達式);
- 可能會在Composite的構造過程當中要求類型安全的運行時檢查。
7.6.(P155)用Command替換條件調度程序:爲動做建立Command,將這些Command存儲在集合中,再經過集合取出對應的Command執行。
缺點與優勢:
+ 提供了用統一方法執行不一樣行爲的簡單機制;
+ 容許在運行時改變所處理的請求,以及如何處理請求;
+ 僅僅須要不多的代碼實現;
- 會增長設計的複雜度,有時還不如條件調度程序簡單。
8.6.(P208)提取Adapter:一個類適配了多個版本的組件、類庫、API或其餘實體,能夠經過提取Adapter來統一接口。
缺點與優勢:
+ 隔離不一樣版本的組件、類庫或API之間的區別;
+ 使類只負責適配代碼的一個版本;
+ 避免了頻繁地修改代碼;
- 由於Adapter帶來的限制,阻止了客戶調用Adapter沒有提供的功能。
8.5.(P99)經過Adapter統一接口:使用客戶代碼與多個類交互時,遵循統一接口完成。
優勢與缺點:
+ 客戶經過相同的接口與不一樣的類交互;
+ 客戶經過公共的接口與多個對象交互;
+ 客戶與不一樣的類交互方式相同;
- 當類的接口能夠改變的時候,增長了設計的複雜度。
Adapter用來適配對象;
Facade用來適配整個子系統;一般用來與遺留系統進行交互。
它們均可以使代碼易於使用,可是它們的應用級別不一樣。
9.1.(P231)用類替換類型代碼:保護字段從而避免不正確或者不安全的賦值。
採用類替換類型代碼而不用枚舉,是由於類能夠考慮將來行爲的擴展,可是如今Java的枚舉功能更增強大了,因此能夠根據本身的習慣來選擇。
當重構過程當中產生的類須要擴展包含更多行爲時,就能夠考慮(7.4.State替換狀態改變條件語句)進行重構了。
缺點與優勢:
+ 避免非法賦值和比較;
- 比使用不安全類型須要更多的代碼。
7.4. 用State替換狀態改變條件語句:簡化複雜的狀態轉換邏輯
優勢與缺點:
+ 減小複雜的狀態轉換條件邏輯;
+ 簡化複雜的狀態改變邏輯;
+ 提供觀察狀態改變邏輯的角度;
- 增長設計的複雜度。
9.3. 引入Null Object:替換掉null的判斷邏輯,提供了對null的正確處理。
優勢與缺點:
+ 不須要重複的null邏輯就能夠避免null錯誤;
+ 經過最小化null測試簡化了代碼;
- 當系統不太須要null測試的時候,會增長設計的複雜度;
- 若是程序員不知道Null Object的存在,就會產生多餘的null測試;
- 使維護變得複雜,擁有超類的Null Object必須重寫全部新繼承到的公共方法。
6.6. 將Singleton內聯化:把Singleton的功能搬移到須要它的類中,而後刪除Singleton。
優勢與缺點:
+ 使對象的協做變得更加明顯和明確;
+ 保護了單一的實例,並且不須要特別的代碼;
- 當在許多層次間傳遞對象實例比較困難的時候,增長了設計的複雜度。
9.2. 用Singleton限制實例化:減小內存的佔用,提升運行的速度。
優勢與缺點:
+ 改進性能;
- 變成全局訪問;
- 當對象含有不能共享的狀態時,重構沒法進行。
8.4.(P190)用Observer替換硬編碼的通知:
優勢與缺點:
+ 使主題及其觀察者訪問鬆散耦合;
+ 支持一個或多個觀察者;
- 增長設計的複雜度;
- 面對串聯通知的時候,會進一步增長設計的複雜度;
- 當觀察者沒有從主題中刪除的時候,會形成內存泄漏。
注:例子不熟悉,因此代碼沒太能領悟
7.3. (P115)將裝飾功能搬移到Decorator:
優勢與缺點:
+ 將裝飾功能從類中搬移去除能夠簡化類;
+ 有效地將類的核心職責與裝飾功能區分開;
+ 能夠去除幾個相關類中重複的裝飾邏輯;
- 改變了被裝飾對象的對象類型;
- 會使代碼變得難以理解與調試;
- 當Decorator組合產生負責影響的時候會增長設計的複雜度。
注:這部分的代碼也不完備,理解起來有困難,建議大體瞭解做者思路就行了,Decorator應該是個應用比較普遍的模式,之後本身能夠經過實踐探索。
+ 均可以去除與特殊狀況或選擇性行爲相關聯的條件邏輯;
+ 都經過把條件邏輯搬移不對勁新的類中達到這一目的;
- Decorator主要把本身包裝在一個對象以外
- Strategy則用在一個對象之中。
11.2.(P278)統一接口:找出全部子類的公共方法,複製到超類中,在超類中執行空行爲。
11.3.(P280)提取參數:經過客戶代碼提供的參數對字段進行賦值。
注:這兩節都是輔助Decorator進行重構的。
6.2.(P51)將建立知識搬移到Factory:避免建立代碼處處蔓延。
優勢與缺點:
+ 合併建立邏輯和實例化配置選項;
+ 將客戶代碼與建立邏輯解耦;
- 若是能夠直接實例化,用Factory就會增長設計複雜度。
注:可能做者認爲採用的是HTMLParser的緣由,因此給出的代碼不全,不利於理解重構的含義。
10.2.(P259)將彙集操做搬移到Visitor:適用於從多個對象中彙集信息,適用於從不一樣的對象中彙集信息。使用起來難度較大,首選應該是Collecting Parameter方法(P253,10.1.)。
優勢與缺點:
+ 調節多個算法,使其他適用於不一樣的對象結構;
+ 訪問相同或不一樣繼承結構中的類;
+ 調用不一樣類上的類型特定方法,無需類型轉換;
- 新的可訪問類須要新的接收方法,每一個Visitor中須要新的訪問方法;
- 可能會破壞被訪問類的封裝性;
- 增長了代碼的複雜度。
注:
- 儘可能使用通用接口把互不相同的類轉變成類似的類,而少用Visitor模式。
- Ralph Johnson:大多時候並不須要Visitor,有些時候則是必需要用,別無選擇。
- 可能做者認爲採用的是HTMLParser的緣由,因此給出的代碼不全,不利於理解重構的含義。
8.7.(P217)用Interpreter替換隱式語言
優勢與缺點:
+ 比隱式語言更好的支持語言元素的組合;
+ 不須要新的代碼來支持語言元素的新組合;
+ 容許行爲的運行時配置;
- 會產生定義語法和修改客戶代碼的開銷;
- 若是語言很複雜,編程工做量較大;
- 若是語言很簡單,不須要考慮使用這個模式,不然會增長設計的複雜度。
2019.1.2.晨,結束閱讀。學習代碼下載
注:這種讀書筆記對他人幫助不大,由於這個只是爲了進一步理解做者的意圖而進行的工做,經過輸入關鍵點來確認本身是否真正領悟了做者想表達的意思。
當輸入這些優勢與缺點時並無領悟,而後再經過輸入代碼來理解做者如何從一段很差的代碼重構成一段好代碼的,重構的過程當中獲得了什麼、失去了什麼,本身將來編寫程序中應該如何平衡。
補充1:不要在乎輸入代碼中出現的錯誤,那是由於代碼不完備,許多類或者函數沒有提供源代碼。只要輸入的代碼能夠排版和使用自動提示工具,就說明代碼符合Java的語法規範,那麼在閱讀全書的過程當中能夠一點點把代碼補全,或者根據本身的理解補全(這也是個理解重構和提升編碼能力的機會)。
補充2:若是須要下載HTMLParser,請注意是1.3的版本纔是做者使用的。可是與HTMLParser相關的例子與原代碼並不徹底相同,而做者並無在本身的例子中把邏輯構造完整,所以建議跟HTMLParser相關的例子仍是跳過吧,不然爲了調試經過消耗時間太多。(我如今開始渴望直接看《重構》那本書了。)
代碼目錄:
貸款風險估算程序(6.1,7.2,8.1,11.1)
HTMLParser(6.2,7.3,8.2,10.1,10.2,11.2,11.3)
對象-關係數據映射(6.3)
XMLBuilder(6.4,6.5,7.5,8.5)
二十一點遊戲(6.6)
集合類庫(7.1)
SystemPermission(7.4,9.1,9.2)
Product(8.3,8.7)
CatalogApp(7.6)
JUnit(8.4)
數據庫查詢(8.6)
Applet(9.2)