(写在最前:还没入门的搬砖工的一本正经的胡说八道)
引言: 最近做到的项目中,需要给对接方提供一个公共接口,根据对方传入的XML文件的rootelement分发调用接口,最简单的使用if-else if 模式,但是看着实在太蠢。
场景一:需要根据关键字,进行接口分发
使用if-else模式缺点:
- 看着蠢
- 不易阅读(个人观点)
- 不易维护
- balabala...不想编了,就是看着不爽
如果只有一两个方法还好,如果方法多了,额。。。如下,自行体会。
1 public class TestMethod { 2 3 public Object dispatchMethod(String name, String data) { 4 Object obj = null; 5 6 if ("methodA".equal(name)) { 7 obj = methodA(data); 8 } else if ("methodB".equal(name)) { 9 obj = methodB(data); 10 } else if (...) { 11 ... 12 } 13 return obj; 14 } 15 16 private Object methodA(String data) { 17 ... 18 } 19 20 private Object methodB(String data) { 21 ... 22 } 23 24 ... 25 }
那么步入正题,我才用的反射模式,匹配目标方法,我认为可以降低维护和阅读成本
开发环境:jdk1.8
实现代码:
- 定义目标方法枚举,包含rootelement信息,调用方法说明,目标方法targetName
1 public enum MethodEnum { 2 3 METHODA("MethodA","调用方法A","methodA"), 4 METHODB("MethodB","调用方法B","methodB"), 5 ; 6 7 @Getter 8 private String code; //rootelement 9 10 @Getter 11 private String message; 12 13 @Getter 14 private String name; //目标方法名 15 16 private MethodEnum (String code,String message,String name) { 17 this.code = code; 18 this.message = message; 19 this.name = name; 20 } 21 22 public static MethodEnum fromCode(String code) { //根据传入code,筛选目标方法 23 for (DockingFliggyHotelEnum p : DockingFliggyHotelEnum.values()) { 24 if(p.code.equalsIgnoreCase(code)) { 25 return p; 26 } 27 } 28 return null; 29 } 32 }
- 定义反射方法工具类
1 /** 2 * 定义工具类 3 **/ 4 public class MethodUtil { 5 6 public static Method getTargetMethod(Class clazz, String methodName) { 7 Method[] methods = clazz.getDeclaredMethods(); //获取所有方法,包含private 8 if (methods != null && methods.length > 0) { 9 String regEx = "^" + methodName +"$";//获取所要查找到的方法名称要匹配此正则 10 Pattern pattern = Pattern.compile(regEx); 11 for (Method method : methods) { 12 Matcher matcher = pattern.matcher(method.getName()); 13 boolean rs = matcher.find(); 14 if(rs){ 15 return method; 16 } 17 } 18 } 19 return null; 20 } 21 22 public static Object executeTargrtMethod(Class clazz, String methodName, String xmlData) { 23 Object obj = null; 24 try { 25 Method method = getTargetMethod(clazz, methodName); 26 obj = method.invoke(clazz, xmlData); 27 } catch (Exception e) { 28 29 } 30 return obj; 31 } 32 33 }
- 具体分发
1 public class TestDispatch { 2 3 public Object dispatch(String root, String xml) { 4 String name = MethodEnum.fromCode(root).name; 5 Object obj = executeTargrtMethod(this.getClass(), name, xml) 6 return obj; 7 } 8 9 private Object methodA(String xml) { 10 Object obj = null; 11 ... 12 return obj; 13 } 14 15 private Object methodB(String xml) { 16 Object obj = null; 17 ... 18 return obj; 19 } 20 21 ... 22 }
对于业务代码结构清晰明了,是不是看着爽多了。
对于类似的场景很多,都可以使用反射机制。
场景二:项目中多处需要大批量插入数据,提取一个公共方法,减少代码行数,何乐而不为呢?
对了,顺便说一下这个批量插入方法,数据库使用mysql,项目框架springboot,jdk1.8,5000条数据插入一次,耗时0.8s左右。
1 /** 2 * @param batchCount 一次批量插入数据量 3 * @param target 目标方法关键字 4 * @param list 需要插入的大批量数据 5 * @throws Exception 6 */ 7 public static void batchInsert(Class clazz, int batchCount, String target, List<?> list) throws Exception{ 8 Method method = getTargetMethod(target); 9 int batchLastIndex = batchCount - 1;//每批最后一个的下标 10 for(int index = 0; index < list.size()-1;){ 11 if(batchLastIndex > list.size()-1){ 12 batchLastIndex = list.size() - 1; 13 if (method != null) { 14 method.invoke(clazz,list.subList(index, batchLastIndex)); 15 } 16 break;//数据插入完毕,退出循环 17 }else{ 18 if (method != null) { 19 method.invoke(clazz,list.subList(index, batchLastIndex)); 20 } 21 index = batchLastIndex + 1;//设置下一批下标 22 batchLastIndex = index + (batchCount - 1); 23 } 24 } 25 }
实验结束,代码分析下次在写了。
写在最后
代码是伪代码,可能啥地方写得不对,欢迎指正
对于以上两种场景,我目前只能想到这种方法。。。如果你有更好的,欢迎来怼我
时间: 2024-10-26 19:21:42