重構:改善既有代碼的設計 要點總結

壞味道

特徵

情況及處理方式

目標

重複代碼

1.重複的表達式
2.
不同算法做相同的事
3.
類似代碼

同一個類的兩個函數有相同表達式

重複代碼提取爲方法

相同表達式只在一個類的一個方法出現,供其他方法調用

兄弟類含有相同表達式

重複代碼提取爲方法
提升方法到父類

不相干類含有相同代碼

提取爲獨立類供調用

過長函數

1.代碼前面有註釋
2.
條件表達式
3.
循環

 

提取方法

每個方法只做一件事,方法要定義完善、命名準確

過大的類

1.一個類中有太多實例變量
2.
一個類中有太多代碼

部分字段之間相關性高

相關的字段和方法提取爲類

每個類負責一組具有內在的相互關聯的任務

某些字段和方法只被某些實例用到

這些字段和方法移到子類中

過長參數列

1.參數列過長
2.
參數列變化頻繁

方法可以通過其他方式獲取該參數

讓參數接受者自行獲取該參數

只需要傳給函數足夠的、讓其可以從中獲取自己需要的東西就行了

同一對象的若干屬性作爲參數

在不使依賴惡化的情況下,使用整個對象作爲參數

被調用函數使用了另一個對象的很多屬性

將方法移動到該對象中

某些數據缺乏歸屬對象

首先創建對象

發散式變化

一個類受多種變化的影響

類經常因爲不同的原因在不同的方向上發生變化

將特定原因造成的所有變化提取爲一個新類

針對某一外界變化的所有修改,只應發生在單一類中,而這個類中所有的內容都應反映此變化

散彈式修改

一種變化引發多個類的修改

某種變化需要在許多不同的類中做出小修改

把所有需要修改的代碼放進同一個類中

針對某一外界變化的所有修改,只應發生在單一類中,而這個類中所有的內容都應反映此變化

依戀情結

一個函數使用其他類屬性比使用自身類屬性還要多

某個函數從另一個對象調用了幾乎半打的取值函數

將依戀代碼提取爲單獨方法,移動到另一對象

將數據和對數據的操作行爲包裝在一起

數據泥團

同時使用的相關數據並未以類的方式組織
1.
兩個類中相同的字段
2.
許多函數中相同的參數

 

先將字段提取爲類,再縮減函數簽名中的參數

總是綁在一起的數據應該擁有屬於它們自己的對象

基本類型偏執

過多使用基本類型

總是被放在一起的基本類型字段

提取類

將單獨存在的數據值轉換爲對象

參數列中有基本類型

提取參數對象

數組中容納了不同的對象,需要從數組中挑選數據

用對象取代數組

基本數據是類型碼

使用類替換類型碼

帶條件表達式的類型碼

使用繼承類替換類型碼

Switch語句

相同的switch、case語句散佈於不同地方

根據類型碼進行選擇的switch

使用多態替代switch

避免到處做相同的修改

單一函數中有switch

使用顯式的方法取代參數

平行繼承體系

1.爲某個類增加子類時,必須爲另一個類增加子類
2.
某個繼承體系類名前綴和另一個繼承體系類名前綴相同

 

一個繼承體系中的實例引用另一個繼承體系中的實例,然後遷移成員

避免到處做相同的修改

冗贅類

類無所事事

父類和子類無太大差別

將它們合爲一體

 

某個類沒有做太多事情

將這個類所有成員移到另一個類中,刪除它

誇誇其談未來性

 

某個抽象類沒有太大作用

將父子類合併

 

不必要的委託

將這個類所有成員移到另一個類中,刪除它

函數的某些參數未用上

移除參數

函數名稱帶有多餘的抽象意味

重命名函數名

函數只被測試方法調用

連同測試代碼一併刪除

令人迷惑的暫時字段

1.某個實例字段僅爲某種情況而設
2.
某些實例字段僅爲某個函數的複雜算法少傳參數而設

 

提取單獨的類,封裝相關代碼

 

過度耦合的消息鏈

一長串的getThis或臨時變量

客戶類通過一個委託類來取得另一個對象

隱藏委託

消除耦合

中間人

某個類接口有大量的函數都委託給其他類,過度使用委託

有一半的函數

移除中間人

 

少數幾個函數

直接調用

中間人還有其他行爲

讓委託類繼承受託類

狎暱關係

某個類需要了解另一個類的私有成員

子類過分了解超類

將繼承改爲委託,把子類從繼承體系移出

封裝

類之間雙向關聯

去掉不必要的關聯

類之間有共同點

提取新類

異曲同工的類

兩個函數做同一件事,但是簽名不同

 

合併

 

不完美的類庫

類庫函數構造的不夠好,又不能修改它們

想修改一兩個函數

在調用類增加函數

 

想添加一大堆額外行爲

使用子類或包裝類

幼稚的數據類

某個類除了字段,就是字段訪問器、設置器

 

1.用訪問器取代public字段
2.
恰當封裝集合
3.
移除不需要的設置器
4.
搬移對訪問器、設置器調用方法到此類
5.
隱藏訪問器、設置器

封裝

被拒絕的饋贈

派生類僅使用了基類很少一部分成員函數

子類拒絕繼承超類接口

使用委託替代繼承

 

過多的註釋

一段代碼有着長長的註釋

 

消除各種壞味道

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章