1 Pull Up Field(字段上移) 和 Pull Up Method(函數(shù)上移)
將字段或者函數(shù)移動到超類。
Motivation:避免重復(fù)。重復(fù)意味著滋生錯誤的可能性和修改的不便性。
做法:
- 檢查,保證需要提升的是完全一致的。
- 如果不相同,則將子類對應(yīng)的修改成父類上你想要表現(xiàn)的形式。
- 在超類中建立要提升的。
- 移除一個待提升的子類屬性。
- 編譯,測試。
- 不斷移除子類上的特性,知道剩下超類的特性。
2 Pull Up Constructor Body(構(gòu)造函數(shù)本體上移)
在各個子類中擁有一些構(gòu)造函數(shù),它們本體幾乎一致。在超類中新建一個構(gòu)造函數(shù),并在子類構(gòu)造函數(shù)中調(diào)用它。
Motivation:任何情況下發(fā)現(xiàn)子類中有共同的行為,都應(yīng)該將共同行為提煉到一個獨立函數(shù)中,并將之提升到超類中。如果構(gòu)造函數(shù)中復(fù)雜的部分難以直接放到父類的構(gòu)造函數(shù)中,可以先Extract Method,而后Pull Up Method。
- 在超類中定義一個構(gòu)造函數(shù)。
- 將子類構(gòu)造函數(shù)中的公共代碼搬移到超類構(gòu)造函數(shù)中。
- 將子類構(gòu)造函數(shù)中的共同代碼刪掉,改而調(diào)用新建的超類構(gòu)造函數(shù)。
- 編譯測試。
3 Push Down Method(函數(shù)下移) 和 Push Down Field(字段下移)
超類的字段或者函數(shù)只被部分子類用到,下發(fā)到子類中去。
4 Extract Subclass(提煉子類)
類中的某些特性值被某些(而非全部)實例用到。新建一個子類,將上面所說的那一部分特性移動到子類中。
Motivation:類中的某些行為只被一部分實例用到,其他實例不需要它們。但是往往Extract Class和Extract Subclass是可以替代的,在兩者之間做選擇是很重要的。Extract Subclass顯然在對象一旦創(chuàng)建完成之后,無法再改變與類型相關(guān)的行為。但如果使用Extract Class,只需要插入另一個組件就可以改變對象的行為。
做法:
- 為源類定義一個新的子類。
- 為這個新的子類提供函數(shù)。
- 找出調(diào)用超類構(gòu)造函數(shù)的所有地點。如果是需要的子類,將之替換為新的構(gòu)造函數(shù)。
- 逐一使用Push Down Method和Push Down Field將源類的特性下發(fā)到子類。
- 找到所有可由繼承體系自身傳達(dá)的信息字段。
- 每次下移之后,編譯并測試。
5 Extract SuperClass(提煉超類)
兩個類有相似特性,為這連個類建立超類,將相似特性移動到超類中。
Motivation:為了避免重復(fù)代碼。
6 Extract Interface
將若干客戶使用類中的共同行為,形成相同子集,并提煉到獨立接口中。
7 Collapse Hierarchy(折疊繼承體系)
子類約等于超類,那么將它們合為一體。
8 From Template Method(塑造模板函數(shù))
當(dāng)子類中相應(yīng)的某些函數(shù)以相同順序執(zhí)行類似的操作,但各個操作的細(xì)節(jié)上有所不同。將這些操作分別放入獨自的函數(shù)中,并保持它們都有相同的簽名,于是源函數(shù)也就變得相同了。然后將源函數(shù)上移到超類。 **
Motivation:主要是能利用多態(tài)減少重復(fù)代碼,并常見的一種情況是:兩個函數(shù)以相同順序執(zhí)行大致相近的操作,但是各操作不完全相同。這種情況將操作序列移動至超類,并借助多態(tài)的差異性。
做法:
- 在各個子類中國分解目標(biāo)函數(shù),使分解后的各個函數(shù)不完全相同,要不完全不同。
- 運(yùn)用Pull Up Method將各自類內(nèi)完全相同的函數(shù)上移至超類。
- 對于那些完全不同的函數(shù),試試Rename Method,使函數(shù)簽名也完全相同。
- 修改上述簽名后,編譯并測試。
- 運(yùn)用Pull Up Method 移動所有源函數(shù)至超類。超類中將各種不同操作定義成抽象函數(shù)。
- 編譯,測試。
- 移除其他子類中的原函數(shù),每刪除一個,編譯并測試。
9 Replace Inheritance with Delegation
在子類中新建一個字段用以保存超類;調(diào)整子類函數(shù),令它改而委托超類;然后去掉兩者之間的繼承。
Motivation:當(dāng)父類中的許多操作并不真正適用于子類。這是可以用委托取代繼承。
- 在子類中建立一個字段,引用超類的實例,并初始化為this。
- 修改子類中的所有函數(shù),讓她們不再使用超類,轉(zhuǎn)而使用上述那個受托字段。
- 去除繼承關(guān)系,新建對象接受受托字段。
- 正對客戶端所用的每一個超類函數(shù),為它添加一個簡單的委托函數(shù)。
- 編譯測試。
10 Replace Delegation with Inheritance
如果是整個接口都被委托,那么繼承它吧。