1、重復代碼
解決方案:
2、函數過長和參數列過長
修改點:
解決方案:
3、過大的類
解決方案:提煉新的獨立類或者子類
4、參數列過長
解決方案:
5、發散式變化(一個類受多種變化影響,貌似就是單一職責原則)目標:外界變化和需要修改的類一一對應
修改點:軟件一旦發生多種變化,但是都修改同一個類,說明此類職責重復
解決方案:找出某種特殊原因造成的所有變化,然后將它們提取到另一個類里面
6、霰彈式修改(一個變化修改多個類)目標:外界變化和需要修改的類一一對應
修改點:軟件一旦發生變化,造成要修改很多類
解決方案:找出某種變化引起的不同類中的眾多修改點,將各個類中修改點放到一個類中
7、依戀情節
修改點:
當一個類的函數為了計算經常調用另一個類的一大堆的函數時就表示出現了依戀情節。
1和0的世界里面出現了如此具有文藝氣質的詞,那么我們就用文藝的手法去理解:你們家的女朋友經常去找別人家的漢子時,你多多少少需要知道壞了。
解決方案:
如果這段代碼完全依戀另一個類,那么將此部分出現依戀情節的代碼提煉成函數放到另一個類里面(這告訴我們當一個女人完全不愛你的時候要學會放手?)
然而很多時候并非這么簡單,它兩個類都有依戀呢?(然而很多時候并非這么簡單,她兩個都愛呢?)
那就判斷哪個類擁有最多被此函數使用的數據,然后就把此函數和那些數據擺在一起。(判斷她愛哪個的優點多一點,就讓她去找誰吧?)
難怪大家都說程序員都是好男人@_@
然而Martin大神多說了一句:
如果先提取方法將這段代碼分割成不同的數個較小的獨立函數上述步驟會簡單很多。(請恕我直言,左腿和左手我要了,刀交給你了,你隨意?)
8、數據泥團
修改點:
所謂數據泥團就是指那些經常一起出現的數據,比如一些經常一起出現的參數,舉個例子:分頁參數
解決方案:
數據泥團應該擁有他們自己的類,就像幾個好基友需要讓他們住在一起
9、基本類型偏執
解決方案:
使用一些小對象比如郵編類,電話號碼類將此類數據應用起來
使用枚舉類型將或者小對象去替代那些類型碼
10、少用Switch
解決方案:
11、平行繼承體系
修改點:每當你為某個類增加一個子類時,必須為另外一個類增加子類,那么就有問題
解決方案:讓一個繼承體系的實例去引用另一個繼承體系
12、冗贅類
解決方案:如果某個類失去了價值,應該將其去掉,比如父子類之間區別不大,那么可以合并,或者將其搬移到另一個類里
13、夸夸其談未來性
不要去考慮未來性,如果用不到就不值得,未來的事情就交給未來,做好現在的事情即可
14、令人迷惑的暫時字段
修改點:某個實例變量僅為某種特定情況而設,這樣的代碼就會不易理解,因為你會認為所有時候都會需要它的所有變量。
解決方案:
15、過度耦合的消息鏈
修改點:一個對象請求另一個對象,然后后者再請求一個變量,然后后者再請求一個變量這就是消息鏈
解決方案:
隱藏委托,在前一個類中寫一個函數直接調用第三個類的函數,即嘗試把函數鏈寫在第一個類的一個新函數中
16、中間人
修改點:
過度運用委托關系
解決方案:
17、狎昵關系
當看到這兩個字的時候我查了一下字典,狎妓的狎(xia),一個比較猥瑣的字眼,當然你不介意的話也可以稱為搞基關系.
修改點:
搞基關系的意思是,兩個類之間花太多時間探究彼此的PRivate部分,就像兩個男人喜歡探究對方的私處一樣。
解決方案:
18、異曲同工的類
解決方案:
其實差不多就是重復代碼的問題,就是兩個做相同事情的函數或者類,唯一的區別在于,當這兩個類差不多的情況下可以提取一個父類
來解決問題
19、不完美的庫類
修改點:
簡而言之就是別人寫的類不好用時,就比如一個引用的動態鏈接庫,你又改不了這個東西時
解決方案:
以下并不是重構作者的解決方案:
因為這本書真的是太老了
對于應用.net的我們可以考慮用一下partial類或者擴展函數
partial類示例:
namespace 重構測試程序{ class Program { static void Main(string[] args) { var test = new Encoding(); Console.WriteLine(test.我就是個中文函數你拿我怎樣吧()); Console.ReadKey(); } }}namespace System.Text { public partial class Encoding { public string 我就是個中文函數你拿我怎樣吧() { return "有種你打我啊"; } }}
擴展函數示例(老實說我在實際項目中沒用過這玩意,這玩意雖好,但是吃螃蟹的恐懼讓我并不敢用):
namespace 重構測試程序{ class Program { static void Main(string[] args) { var test = new StringBuilder(); Console.WriteLine(test.我叫擴展函數("Troy123")); Console.ReadKey(); } } public static class 中文編碼類 { public static string 我叫擴展函數(this object obj, string name)//擴展函數 { return name + "最喜歡寫測試代碼的時候用中文了"; } }}
20、純稚的數據類
修改點:
就是說這個類擁有一些字段,并且有一些讀寫這個字段的函數
更簡單的說就是不用公共字段,不要把需要隱藏的東西暴露出來(不要把你的私處暴露出來(#‵′)凸)
解決方案:
字段封裝成方法來調用(.NET的我們用屬性就好了)
特別是對于容器類的字段要控制好它的封裝,
21、被拒絕的遺贈
修改點:
當子類不需要繼承父類多余的屬性和方法時
這個修改點在Martin看來一般并不是很嚴重,很多時候可以不去理睬,這個視具體情況而定
我的理解是,如果子類繼承多余的東西并沒有引起誤解和較差的可讀性,那么其實可以不理睬
解決方案:
22、過多的注釋
修改點:
這里并不是說注釋不重要,而是說你這段過多的注釋可能是因為你有一段超爛的代碼而導致你不得不寫這么多注釋
注釋除了用于標注將來之外,更應該用在你那些并無把握的地方,而不是為了一段超爛的但是你理解了的代碼寫一段超長的注釋。
解決方案:
新聞熱點
疑難解答