項目中太多的if...else 添加需求 又需要添加一個 else if() ...? 擴(kuò)展性及其不好.
首先在知乎上看到一個大神的解決方案,非常的不錯.
https://zhuanlan.zhihu.com/p/33383648
實現(xiàn)原理:? 通過策略模式+工廠模式+反射解決了 if else 的問題
比如有N多家 銀行 的 計算方法都 不同 ,如果用 if ..else 去編寫代碼,那會非常的不好,代碼中 if .. else 會非常多? 也不符合 開閉原則
比如有2家 一家是 農(nóng)業(yè)銀行 , 一家是 工商銀行 , 用枚舉來定義 銀行的列表, 這樣返回給前段的時候? ?枚舉名稱就是 銀行的 type
自定義注解:
在策略的具體實現(xiàn)類上面 標(biāo)注這個 注解
策略接口:
策略實現(xiàn)類:
通過工廠來創(chuàng)建對象:
ClassUtil的代碼:
public class ClassUtil {public static HashMapgetClasses(String pack) {// 定義一個MAP用于存放type 和類路徑的映射HashMapmap = new HashMap();// 是否循環(huán)迭代boolean recursive = true;// 獲取包的名字 并進(jìn)行替換String packageName = pack;String packageDirName = packageName.replace('.', '/');// 定義一個枚舉的集合 并進(jìn)行循環(huán)來處理這個目錄下的thingsEnumerationdirs;try {dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);// 循環(huán)迭代下去while (dirs.hasMoreElements()) {// 獲取下一個元素URL url = dirs.nextElement();// 得到協(xié)議的名稱String protocol = url.getProtocol();// 如果是以文件的形式保存在服務(wù)器上if ("file".equals(protocol)) {// 獲取包的物理路徑String filePath = URLDecoder.decode(url.getFile(), "UTF-8");// 以文件的方式掃描整個包下的文件 并添加到集合中findAndAddClassesInPackageByFile(packageName, filePath,recursive, map);}}} catch (IOException e) {e.printStackTrace();}return map;}@SuppressWarnings("rawtypes")public static void findAndAddClassesInPackageByFile(String packageName,String packagePath, final boolean recursive,Map map) {
// 獲取此包的目錄 建立一個File
File dir = new File(packagePath);
// 如果不存在或者 也不是目錄就直接返回
if (!dir.exists() || !dir.isDirectory()) {
// log.warn("用戶定義包名 " + packageName + " 下沒有任何文件");
return;
}
// 如果存在 就獲取包下的所有文件 包括目錄
File[] dirfiles = dir.listFiles(new FileFilter() {
// 自定義過濾規(guī)則 如果可以循環(huán)(包含子目錄) 或則是以.class結(jié)尾的文件(編譯好的java類文件)
public boolean accept(File file) {
return (recursive && file.isDirectory())
|| (file.getName().endsWith(".class"));
}
});
// 循環(huán)所有文件
for (File file : dirfiles) {
// 如果是目錄 則繼續(xù)掃描
if (file.isDirectory()) {
findAndAddClassesInPackageByFile(
packageName + "." + file.getName(),
file.getAbsolutePath(), recursive, map);
} else {
// 如果是java類文件 去掉后面的.class 只留下類名
String className = file.getName().substring(0,
file.getName().length() - 6);
try {
String fullPath = packageName + '.' + className;
// 使用注解塞map
Class clazz = Class.forName(fullPath);
Annotation[] annotations = clazz.getAnnotations();
for (Annotation annotation : annotations) {
//可以根據(jù)類型判斷? 讀取不同類型 注解的值? put map 中
Pay pay = (Pay)annotation;
map.put(String.valueOf(pay.value()),fullPath);
}
} catch (ClassNotFoundException e) {
// log.error("添加用戶自定義視圖類錯誤 找不到此類的.class文件");
e.printStackTrace();
}
}
}
}
}
策略上下文對象:
測試類代碼:
這是一位大神實現(xiàn)的方式...........................................
下面來談?wù)勎业睦斫?
可以用注解來標(biāo)注實現(xiàn)類
枚舉來定義具體多少種類型
這樣的話 通過注解和枚舉的組合來反射實例化具體的實現(xiàn)類,最后調(diào)用不通的策略實現(xiàn). 你get 到了 嗎?