4 在物件之間搬移特性

2021-08-27 20:12:37 字數 2271 閱讀 5733

在物件的設計過程中,「[color=red]決定把責任放在哪兒[/color]」即使不是最重要的事,也是最重要的事之一。常常只需要使用[color=red]move method和move field[/color]簡單地移動物件行為,就可以解決這些問題。如果這兩個手法都需要用到,建議先使用move field再使用move method。

[b]類往往會因為承擔[color=red]過多責任[/color]而變得臃腫不堪[/b]。這時可以使用extract class將一部分責任分離出去。如果乙個類變得「不負責任」,就使用inline class將它融入另乙個類。如果乙個類使用了另乙個類,運用hide delegate將這種關係隱藏起來通常是有幫助的。有時候隱藏委託類會導致擁有者的介面經常變化,此時需要使用remove middle man。

[b]4.1 move method(搬移函式)[/b]

程式中,有個函式與其所駐類[b]之外[/b]的另乙個類進行更多交流,呼叫後者或被後者呼叫。就在該函式最常引用的類中建立乙個由類似行為的新函式,將舊函式變成乙個單純的委託函式,或是將舊函式完全移除。有時候搬移一組函式比逐個搬移更簡單些。

[img]

就像圖中amethod()方法老是與class2互動,那乾脆讓它們在一起好了。把功能放到class2中,然後class1只是直接或間接呼叫這個方法即可。

[b]4.2 move field (搬移字段)[/b]

程式中某個[b]字段[/b]被其所駐類[b]之外[/b]的另乙個類更多地用到,就可以在目標類新建乙個字段,修改源字段的所有使用者,令它們改用新字段。

[img]

在類之間移動狀態和行為,是重構過程中必不可少的措施。上述所謂使用可能是通過getter/setter間接進行的。

[b]4.3 extract class (提煉類)[/b]

[img]

可以結合move field和move method來達到拆分的目的。[color=red]拆分原則就是單一職責,乙個類只做一件事情。[/color]

[b]4.4 inline class (將類內聯化)[/b]

某個類沒有做太多事情,就將這個類所有特性搬移到另乙個類中,然後移除原類。

[img]

[b]inline class正好與extract class相反[/b]。[b]需要判斷要消除的類的語義是否跟要融入的類的語義接近。[/b]

[b]4.5 hide delegate (隱藏委託關係)[/b]

客戶通過乙個委託類來呼叫另乙個物件。在服務類上建立客戶所需的所有函式,用以隱藏委託關係。

[img]

「封裝」即使不是物件的最關鍵特徵,也是最關鍵特徵之一。「封裝」意味著每個物件都應該盡可能少了解系統的其他部分。如此一來,一旦發生變化,需要了解這一變化的物件就會比較少,這會使變化比較容易進行。

[b]如果某個客戶先通過服務物件的字段得到另乙個物件,然後呼叫後者的函式,那麼客戶就必須知曉這一層委託關係,萬一委託關係發生變化,客戶也得相應變化。[/b]

可以對比4.6的方法,恰當的把握兩者的度真的不是那麼容易,但我們要知曉,委託和直接呼叫之間有那麼乙個「合適的封裝和簡單的委託」關係。

[b]4.6 remove middle man(移除中間人)[/b]

某個類做了[b]過多的簡單委託動作[/b],那就讓客戶直接呼叫受委託類,移除中間人。

[img]

在討論hide delegate時我們談到了「封裝受委託物件」的好處。但是這層封裝也是要付出代價的,每當客戶要使用受委託類的新特性時,就必須在服務端新增乙個簡單委託函式。隨著受委託類的特性越來越多,這一過程會讓你痛苦不已。[b]服務類完全變成了乙個「中間人」,此時就應該讓客戶直接呼叫受託類。[/b]

很難說什麼程度的隱藏才是合適的。還好,有了hide delegate和remove middle man,我們就可以在系統執行過程中不斷進行調整。隨著系統的變化,「合適的隱藏程度」這個尺度也相應改變。

[b]4.7 introduce foreign method (引入外加函式)[/b]

當需要為提供服務的類增加乙個函式,但無法修改這個類時(比如是第三方的類),我們可以在客戶類中建立乙個函式,並以第一引數形式傳入乙個服務類例項。

[img]

[b]4.8 introduce local extension (引入本地擴充套件)[/b]

當需要為服務類提供一些額外函式,但無法修改這個類,可以建立乙個新類,使它包含這些額外函式,讓這個擴充套件類稱為源類的子類或包裝類。

[img]

這與introduce foreign method的區別就是需要擴充套件的方法比較多。[color=red]這也體現了使用組合來代替繼承來達到擴充套件功能的設計思想。[/color]

在物件之間搬移特性(一)

1,move method 搬移函式 要點 在該函式最常引用的類中建立乙個有著類似行為的新函式。將舊函式變成乙個單純的委託函式,或是將舊函式完全移除。2,move field 搬移字段 要點 在目標類新建乙個字段,修改源字段的所有使用者,令它們改用新字段 3,extract class 提煉類 現象...

在物件之間搬移特性(二)

6,remove middle man 現象 某個類做了過多的簡單委託動作 要點 讓客戶之間呼叫受託類。7,introduce foreign method 引入外加函式 現象 你需要為提供服務的類增加乙個函式,但你無法修改這個類 要點 在客戶類中建立乙個函式,並以第一引數形式傳入乙個服務類例項。8...

重構 在物件之間搬移特性

1 move method 搬移函式 有個函式與所在類之外的另乙個類進行更多的交流 呼叫或被呼叫 在該函式最常引用的類中建立乙個有著類似行為的新函式。將舊函式變為乙個單純的委託函式,或者將舊函式刪除。2 move field 搬移字段 某個欄位被其所屬類之外的另乙個類頻繁呼叫。3 extract c...