重構與模式

linlinlinxi007發表於2010-01-27

讀完《重構——改善既有程式碼的設計》和《重構與模式》,有了些許感想,先與大家分享一下。當我們已經對設計模式倒背如流時,卻往往發現在實際程式碼編寫中有生搬硬套的感覺。設計模式是前人經驗的總結,直接拿來用合不合適呢?這讓我想起了大學一位老師告訴我們的一條學習的道路“知識,理論,智慧”。設計模式是很一種優雅的“智慧”,但對於我們初學者來說還僅僅是留存於文字的“知識”。把“知識”融合到自己的開發中,在不斷探索和總結中形成自己“理論”,再應用到實際中,那麼這才是是真正屬於我們自己的“智慧”。重構恰恰是由“知識”到“理論”的必經之路,而書中的各種重構方法無疑是這條路上清晰的路標。

程式碼的壞味道大家一看都不會陌生,絕對是在我們的程式設計中如影隨形的,現在把相應的重構方法和設計模式總結出來,方便自己參考查閱,也希望對大家有所幫助。

友情提示:下面所列出的不是公式,不是別的重構方法不能用,也不是非要重構到相應的設計模式,因為不論是重構還是應用設計模式,一切的目的都是為了軟體構架的“優雅”,而不是炫耀技術。另外,兩位作者在描述重構步驟的時候,都不斷重複著“編譯並通過測試”的步驟,這無疑是在強調測試的重要性,和重構的遞進性,切不可一措而蹴。

程式碼的壞味道 一般重構方法 使用模式重構
重複程式碼 提煉方法
提取類
方法上移
替換演算法
鏈構造方法
構造Template Method
以Composite取代一/多之分
引入Null Object
用Adapter統一介面
用Fatory Method引入多型建立
過長方法 提取方法
組合方法
以查詢取代臨時變數
引入引數物件
保持物件完整
轉移聚集操作到Vistor
以Strategy取代條件邏輯
以Command取代條件排程程式
轉移聚集操作到Collecting Parameter
過長引數列 以方法取代引數
引入引數物件
保持物件完整
 
條件邏輯過度複雜 分解條件式
合併條件式
合併重複的條件片段
移除控制標記
以衛語句取代巢狀條件式
以多型取代條件式
引入斷言
以Strategy取代條件邏輯
轉移裝飾功能到Decorator
以State取代狀態改變條件語句
引入Null Object
分支語句 提取方法
轉移方法
以子類取代型別程式碼
以多型取代條件式
已明確方法取代引數
以State/Strategy取代型別程式碼
引入Null Object
以Command替換條件排程程式
轉移聚集操作到Visitor
基本型別迷戀
程式程式碼過於依賴基本型別(int,string,double,array等低層次語言要素)
以物件取代資料值
以型別取代型別程式碼
以子類取代型別程式碼
提取類
引入引數物件
以物件取代陣列
以State取代狀態改變條件語句
以Strategy取代條件邏輯
以Composite取代隱含樹
以Interpreter取代隱式語言
轉移裝飾功能到Decorator
用Builder封裝Composite
資料泥團
在類的欄位和引數列中,總是一起出現的資料
提取類
引入引數物件
保持物件完整
 
令人迷惑的臨時欄位 提取類 引入Null Object
組合爆炸
許多段程式碼使用不同種類或數量的資料或物件做同樣的事情(例如使用特定條件和資料庫查詢)
  以Interpreter取代隱式語言
過大類 提取類
提取子類
提取介面
複製被監視資料
以Command取代條件排程程式
以State取代狀態改變條件語句
以Interpreter取代隱式語言
冗贅類
不再做很多工作或沒有用的類
摺疊繼承關係
內聯Singleton
 
不恰當的暴露
在客戶程式碼中不應看到類的欄位和方法,卻是公開可見的
封裝欄位
封裝群集
移除設定方法
隱藏方法
用Factory封裝類
發散式變化
類經常因為不同的原因在不同方向上發生變化,顯然是違反了單一職責原則
提取類  
霰彈式修改
如果遇到變化,必須在不同的類中作出相應的修改
轉移方法
轉移欄位
內聯類
將建立知識搬移到Factory
依戀情結
方法對於某個類的興趣高過對自己所處的宿主類
轉移方法
提取方法
引入Strategy
引入Visitor
平行繼承體系
當為一個類增加一個子類時,也必須在另一個類中增加一個相應的子類
轉移方法
轉移欄位
 
誇誇其談未來性 摺疊繼承關係
內聯類
移除引數
移除方法
 
過度耦合的訊息連
不斷的向一個物件索求另一個物件
隱藏委託
提取方法
轉移方法
使用抽象引入Chain Of Responsibility
中間轉手人
類介面中有很多方法都委託給其他類
移除中間轉手人
內聯方法
以繼承取代委託
 
狎暱關係
類之間彼此依賴於其private成員
轉移方法
將雙向關聯改為單向
提取類
隱藏委託
以繼承取代委託
 
異曲同工的類 重新命名方法
轉移方法
提取超類
用Adapter統一介面
不完善的程式庫類 引入外加方法
引入本地擴充套件
用Adapter統一介面
用Facade封裝類
純稚的資料類
只擁有欄位的資料類
封裝欄位
封裝集合
移除設定方法
轉移方法
隱藏方法
 
被拒絕的遺贈
繼承父類時,子類想要選擇繼承的成員
以委託取代繼承  
過多的註釋
為糟糕的程式碼寫大量的註釋
使用一起重構方法,使方法本身達到自說明的效果,讓註釋顯得多餘  
怪異解決方案
在同一系統中使用不同的方式解決同一問題
替換演算法 用Adapter統一介面

相關文章