前言
決定把責任放在哪對於物件設計是最重要的之一。重構可以很好的解決這個問題。以下是筆者的重構方法
注:客戶:呼叫介面
客戶類:使用了介面的類
服務類:提供服務的類
Move Method(搬移函式)。
問題
你的程式中,有個函式與其所駐類之外的另一個類進行更多交流:呼叫後者或者被後者呼叫。
方法
在該函式最常引用的類中建立一個有著類似行為的新函式,將舊函式程式設計一個單純的委託函式,或是將舊函式完全移除。
動機
一個類有太多行為,或者與另一個類有太多合作形成高度耦合,為了讓系統中的類更簡單,乾淨利落地實現系統交付的任務。
Move Field(搬移欄位)。
問題
在你的程式中,某個欄位被其所駐類之外的另一個類更多地用到。
方法
在目標類新建一個欄位,修改源欄位的所有使用者,令它們改用新欄位。
動機
對於一個欄位,在其所駐類之外的另一個類中有更多的函式使用了它。
Extract Class(提煉類)。
問題
某個類做了應該由兩個類做的事情。
方法
建立一個新類,將相關的欄位和函式從舊類搬移到新類。
動機
一個類應該是一個清楚的抽象,處理一些明確的責任,實際工作中,類可能不斷擴大,加入很多新功能,這樣的類往往有大量函式和資料,這樣的類往往不易理解,所以需要提煉類,將其中獨立的功能提煉出來形成新的類。
Inline Class(將類內聯化)。
問題
某個類沒有做太多事情。
方法
將這個類的所有特性搬移到另一個類中,然後移除原類。
動機
正好與Extra Class相反,如果一個類不再承擔足夠責任,不再有單獨存在的理由,就需要將這個類塞進另一個類中。
Hide Delegate(隱藏“委託關係”)。
問題
客戶通過一個委託類來呼叫另一個物件。比如person類(人)呼叫department類(部門)來獲取manager類(經理)
方法
在服務類(人)上建立客戶所需的所有函式,用以隱藏委託關係。
動機
將委託關係隱藏起來,防止委託關係發生變化,客戶也得相應變化,從而去除這種依賴。
Remove Middle Man(移除中間人)。
問題
某個類做了過多的簡單委託動作。
方法
讓客戶直接呼叫受託類。
動機
在Hide Delegate中,封裝受託物件是有好處的,但是也是有代價的:每當客戶要使用受託類新特性,就必須在服務端新增一個簡單委託函式,隨著受託類功能增多,這個過程會讓人痛苦,服務類變成了一個“中間人”,此時應該移除中間人,讓客戶直接呼叫受託類。
Introduce Foreign Method(引入外加函式)。
問題
你需要為提供服務的類增加一個函式,但你無法修改這個類。
方法
在客戶類中建立一個函式,並以第一引數形式傳入一個服務類例項。
動機
使用一個類的時候需要一個新的服務,但是不能修改原始碼,就得在客戶端編碼,補足函式所需功能。但是如果為一個服務類建立了大量外加函式,就不該使用這個重構了,應該用Introduce Local Extension。
Introduce Local Extension(引入本地擴充套件)。
問題
你需要為服務類提供一些額外函式,但你無法修改這個類。
方法
建立一個新類,使它包含這些額外的函式。讓這個擴充套件品成為源類的子類或包裝類。
動機
類的作者也無法預見未來,因此常常沒能為後來者準備足夠有用的函式。如果無法修改原始碼,需要兩個以上外加函式,就需要將這些函式組織在一起,放到一個恰當的地方。
總結
1:“決定把責任放在哪兒” 試用 方法: Move Method , Move Filed ,如果需要都試用先試用 Move field 再使用 Move Method 。
2:類責任過多 —>Extract class 方法
3:類責任太少—> inline class
4:一個類使用另一個類 —> Hide Delegate
5:隱藏委託類導致擁有者的介面經常變化—> Romove Middle Man
6:不能訪問類的原始碼但是想將責任移到不可修改的類中 —> Introduce Foreign Methon(少量函式) & Introduce Local Extension(較多函式)