對于每個編碼人員來說,避免重復代碼可能是大家都想做的。對于有一定經驗(對基本的OO原則有一定經驗)的開發人員來說,大部分情況下都能比較自然地避免重復代碼的問題,寫代碼的時候,感覺有邏輯重復的情況,會很自然的憑感覺經驗做相應的處理和復用。 以下是個人經驗,供新手參考。
既然我們在用Java之類的面向對象的語言編碼,那么重復代碼可以大致分為如下兩種情況:
1、類型體系之內(父類型和子類型、子類型之間)存在重復邏輯代碼
2、類型體系之外的重復代碼
【類型體系內的重復代碼處理】

1、如果重復代碼屬于類型本身操作(即應該是以實例方法存在),則很自然的應用重構技巧,公共代碼往上走。如果Sub Type之間有這種重復代碼,把重復代碼遷移到DefaultAdatper中。
2、如果重復代碼不屬于類型本身操作(即應該是以靜態方法存在),則需要判斷一下這種靜態代碼的功能使用范圍:
A、如果是非常全局性的,例如有關java流的輔助操作,則應該果斷的抽取出來,封裝到一個Utility工具類中,例如可以叫做IOUtil。把這個Utility類放置到非常底層模塊中,這樣上層很多功能模塊中都可以使用,否則可能會導致上層多個模塊中都有類似IOUtil的類,又是重復代碼。
1 public class IOUtil {
2 /**
3 * 工具類,不需要產生實例。 但是也不需要應用單態!!!
4 */
5 private IOUtil() {}
6
7 public static InputStream buildInputSteam(File file) {//
}
8
9 //其他公共靜態操作
10 }
B、如果這種靜態操作只對本類型體系有意義,則有兩種常用的處理方法:第一種是把這種靜態方法遷移到基類DefaultAdapter中,但是不要在DefaultAdapter中放置過多的類似靜態方法;第二種是把這種靜態方法封裝到一個helper助手類中,例如MyTypeHelper,其中放置了MyType類型體系中需要使用的一些靜態方法。如果第一種DefaultAdapter中堆放了較多的靜態方法,則可以用helper助手類的方式。
1 public class MyTypeHelper {
2 /**
3 * 助手類,不需要產生實例。 但是也不需要應用單態!!!
4 */
5 private MyTypeHelper() {}
6
7 public static boolean validateParamer(Object paramer) {//
}
8
9 //其他公共靜態操作
10 }
這個helper一般需要和接口、默認適配類一起暴露,便于擴展子類型使用。示意圖如下:

【類型體系之外的重復代碼處理】
類型體系之外的重復代碼處理相對就很簡單了,根據重復代碼功能適用范圍,封裝到對應的Util類或者Helper類中。這里就不細講了~_~
【有關公用代碼的幾個概念】
個人意見,僅供參考。
助手類(Helper class):我覺得首先這個類產生的目的是為特定模塊或者特定功能服務的(助手嗎~_~),不是全局的。而且完全可以隱藏在特定模塊內部,很多時候不需要暴露。Helper類的命名要有針對性,不能搞成一個麻辣燙,里面的靜態操作既為這種功能服務,又為那種功能服務,盡量做個忠臣,不要同時當多個主子的助手。
工具類(Utility class):一般是全局的,往往有一定普世價值,也就是說往往是全局通用的。
例如你在做一個模塊,這個模塊功能是處理表單,則關于處理表單的一些公用靜態操作就應該放置到該模塊的一個助手類中,名稱類似于FormProcesserHelper。再有一個導出報表的功能,則對應的助手類可以稱之為ExportReportHelper,建議這兩個helper不要混在一起。 有人可能會說,這樣會不會導致大量的助手類呢?這邊有個粒度把握的問題(經驗會發生作用~_~),但是只要是助手類命名規范,則一個助手類的名字就基本上可以告訴用戶你提供什么樣的服務了。
假如你現在處理的是有關IO操作的重復代碼,則需要遷移到全局的工具類中,因為這樣的操作往往適應于全局的。
Facade class(門面類):這個乍看起來和助手類有點像,往往是綁定于特定模塊。但是,要搞清楚,門面類是用來封裝子系統的,代理對模塊常用核心功能的訪問的,針對用戶需要的常用場景提供一些輔助操作,幫助用戶更好的使用此模塊的主要功能。面向客戶端或者其他子系統或模塊的,不是用來處理對應模塊中重復代碼的!!!有關詳細信息,請參加Facade設計模式的文檔。
【注意】Helper class、Utility class、Facade class一般都不需要生實例,暴露的都是靜態操作,更不需要誤寫成單態,別濫用單態!!!
后記::
關于重復代碼的處理,個人以為既需要技巧(別人總結出來的技巧),更需要經驗(經驗往往給你感覺,跟著感覺走一般就不會太離譜~_~)。 希望對開發新手有作用~_~
本博客中的所有文章、隨筆除了標題中含有引用或者轉載字樣的,其他均為原創。轉載請注明出處,謝謝!