项目中 if else 过多的思考

项目中太多的if...else 添加需求 又需要添加一个 else if() ...  扩展性及其不好.

首先在知乎上看到一个大神的解决方案,非常的不错.

https://zhuanlan.zhihu.com/p/33383648

实现原理:  通过策略模式+工厂模式+反射解决了 if else 的问题


比如有N多家 银行 的 计算方法都 不同 ,如果用 if ..else 去编写代码,那会非常的不好,代码中 if .. else 会非常多  也不符合 开闭原则

比如有2家 一家是 农业银行 , 一家是 工商银行 , 用枚举来定义 银行的列表, 这样返回给前段的时候   枚举名称就是 银行的 type



项目中 if else 过多的思考_第1张图片

自定义注解:


项目中 if else 过多的思考_第2张图片


在策略的具体实现类上面 标注这个 注解


策略接口:

项目中 if else 过多的思考_第3张图片

策略实现类:


项目中 if else 过多的思考_第4张图片



项目中 if else 过多的思考_第5张图片




通过工厂来创建对象:


项目中 if else 过多的思考_第6张图片



ClassUtil的代码:

public class ClassUtil {public static HashMapgetClasses(String pack) {// 定义一个MAP用于存放type 和类路径的映射HashMapmap = new HashMap();// 是否循环迭代boolean recursive = true;// 获取包的名字 并进行替换String packageName = pack;String packageDirName = packageName.replace('.', '/');// 定义一个枚举的集合 并进行循环来处理这个目录下的thingsEnumerationdirs;try {dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);// 循环迭代下去while (dirs.hasMoreElements()) {// 获取下一个元素URL url = dirs.nextElement();// 得到协议的名称String protocol = url.getProtocol();// 如果是以文件的形式保存在服务器上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() {

// 自定义过滤规则 如果可以循环(包含子目录) 或则是以.class结尾的文件(编译好的java类文件)

public boolean accept(File file) {

return (recursive && file.isDirectory())

|| (file.getName().endsWith(".class"));

}

});

// 循环所有文件

for (File file : dirfiles) {

// 如果是目录 则继续扫描

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) {

//可以根据类型判断  读取不同类型 注解的值  put map 中

Pay pay = (Pay)annotation;

map.put(String.valueOf(pay.value()),fullPath);

}

} catch (ClassNotFoundException e) {

// log.error("添加用户自定义视图类错误 找不到此类的.class文件");

e.printStackTrace();

}

}

}

}

}


策略上下文对象:


项目中 if else 过多的思考_第7张图片


测试类代码:


项目中 if else 过多的思考_第8张图片




这是一位大神实现的方式...........................................


下面来谈谈我的理解:

可以用注解来标注实现类

枚举来定义具体多少种类型

这样的话 通过注解和枚举的组合来反射实例化具体的实现类,最后调用不通的策略实现. 你get 到了 吗?

你可能感兴趣的:(项目中 if else 过多的思考)