(写在最前:还没入门的搬砖工的一本正经的胡说八道)
引言: 最近做到的项目中,需要给对接方提供一个公共接口,根据对方传入的 XML 文件的 rootelement 分发调用接口,最简单的使用 if-else if 模式,但是看着实在太蠢。
场景一:需要根据关键字,进行接口分发
使用 if-else 模式缺点:
如果只有一两个方法还好,如果方法多了,额。。。如下,自行体会。
- 1 public class TestMethod {
- 2
- 3 public Object dispatchMethod(String name, String data) {
- 4Object obj =null;
- 5
- 6 if("methodA".equal(name)) {
- 7obj = methodA(data);
- 8}else if("methodB".equal(name)) {
- 9obj = 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
实现代码:
- 1 public enum MethodEnum {
- 2
- 3METHODA("MethodA","调用方法A","methodA"),
- 4METHODB("MethodB","调用方法B","methodB"),
- 5 ;
- 6
- 7 @Getter
- 8 private String code; //rootelement
- 9
- 10 @Getter
- 11 private String message;
- 12
- 13 @Getter
- 14 privateString 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 staticMethodEnum 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) {
- 4String name = MethodEnum.fromCode(root).name;
- 5Object obj = executeTargrtMethod(this.getClass(), name, xml)
- 6 return obj;
- 7 }
- 8
- 9 private Object methodA(String xml) {
- 10Object obj =null;
- 11 ...
- 12 return obj;
- 13 }
- 14
- 15 private Object methodB(String xml) {
- 16Object 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
- }
实验结束,代码分析下次在写了。
写在最后
代码是伪代码,可能啥地方写得不对,欢迎指正
对于以上两种场景,我目前只能想到这种方法。。。如果你有更好的,欢迎来怼我
来源: http://www.cnblogs.com/frances9416/p/7119216.html