1、欄位上移修改點:兩個子類擁有相同的欄位做法:將該欄位移至父類2、函數上移修改點:有些函數,在各個子類中產生完全相同的效果做法:將該函數移至父類有一種特殊情況也需要這麼做:子類函數覆蓋了父類的,但是仍然做著相同的工作在此重構中你可能會遇到一種情況,就是你提煉的函數調用了子類有而父類沒有的函數,那麼...
1、欄位上移
修改點:兩個子類擁有相同的欄位
做法:將該欄位移至父類
2、函數上移
修改點:有些函數,在各個子類中產生完全相同的效果
做法:將該函數移至父類
有一種特殊情況也需要這麼做:子類函數覆蓋了父類的,但是仍然做著相同的工作
在此重構中你可能會遇到一種情況,就是你提煉的函數調用了子類有而父類沒有的函數,那麼在父類中給此父類沒有的函數,建立一個虛函數即可。
3、構造函數本體上移
修改點:你在各個子類中擁有一些構造函數,它們的本體幾乎完全一致
做法:在父類中新建一個構造函數,併在子類構造函數中調用它。
4、函數下移
修改點:父類中的某個函數只與部分(而非全部)子類有關
做法:將這個函數移到相關的那些子類去。
5、欄位下移
修改點:父類中某個欄位只被部分(而非全部)子類用到
做法:講這個欄位下移到相關的子類去。
6、提煉子類
修改點:類中的某些特性只被某些(而非全部)實例用到
做法:新建一個類,將上面所說的那一部分特性移至子類
7、提煉父類
修改點:兩個類有相似特性
做法:為這兩個類建立一個父類,將相同特性移至超類
8、提煉介面
修改點:若幹客戶使用類介面中的同一子集,或者兩個類的介面有部分相同
做法:將相同子集提煉到一個獨立介面
意思很簡單,就是將一個類里的一些業務相關的函數,或者是兩個類中部分相同的函數,提取為Interface(這裡不用介面用個英文的原因是在前面的文章中介面一詞可能更多的可以理解為一個類的公共函數)
9、摺疊繼承體系
修改點:父類和子類無太大區別
做法:將它們合為一體
10、塑造模版函數
修改點:你有一些子類,其中相應的某些函數以相同順序執行類似的操作,但各個操作的細節上有所不同
做法:將這些操作分別放進獨立函數中,並保持它們具有相同的簽名,於是原函數也就變得相同了,然後將原函數上移至父類
意思很簡單,就是說你看見有些函數的具體操作不同,但是幾個函數的組合操作順序是一樣的,那麼就把它們的操作順序提煉成函數放進父類。
11、以委托取代繼承
修改點:某個子類只使用父類介面的一部分,或是根本不需要繼承來的數據
做法:在子類中新建一個欄位用以保存父類;調整子類函數,令它改而委托超類;然後去掉兩者之間的繼承關係
動機:隨著需求的變化,一開始的繼承關係可能在慢慢變化後,你就發現父類中的許多操作並不適用於子類
Troy:這個時候你當然可以去把這些不適用子類的方法去搞到另一個子類里,但是如果做不到,那麼就將父類對象作為子類的一個對象吧,去掉繼承關係,這在設計模式裡面貌似可以叫組合模式
12、以繼承取代委托(看吧看吧,總是有相反的兩個重構操作出現)
修改點:你在兩個類之間使用委托關係,並經常為整個介面編寫許多極簡單的委托函數
做法:讓委托類繼承受托類
兩條告誡:
1.如果你並沒有使用受托類的所有函數。那麼你可能不需要使用此方法,你可以去去除中間人,用客戶端直接調用受托類,也可以把委托類和受托類之間提煉出一個超類,當然也可以提取介面
2.受托對象被不止一個其他對象共用,而且受托對象是可變的。那麼這種情況下你也不應該用此重構,因為這樣就無法共用數據了,數據共用是委托關係承擔的一種責任,你無法把它轉化為繼承關係。如果受托對象不可變你才能這麼做。