重構-改善既有程式碼的設計(七)– 在程式碼之間搬移特性

木木甫發表於2019-01-19

前言

決定把責任放在哪對於物件設計是最重要的之一。重構可以很好的解決這個問題。以下是筆者的重構方法
注:客戶:呼叫介面
客戶類:使用了介面的類
服務類:提供服務的類

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(較多函式)

相關文章