拒绝无休止switch


一、前言

  前天碰到个需求,其实很简单,就是Excel导入,Excel模板长下面这样:

  

  按我平常的逻辑是这样做的:

  •   用文件输入流读取Excel,根据Excel的版本生成不同的对象,比如XSSFWorkbook或是HSSFWorkbook
  • new一个工作簿,读取内容
  • 按行遍历,按cell单元格读取
  • 读取到值后,根据业务逻辑进行处理,最后存入entity

  这个需求按这个逻辑下来,循环取值的代码是这样的:

  

 if (CollectionUtils.isNotEmpty(rowList)) {
List<DtTableCheck> data = Lists.newArrayList();
Map<String, String> paramValueMap;
for (int i = 0; i < rowList.size(); i++) {
paramValueMap = Maps.newLinkedHashMap();
DtTableCheck dtc = new DtTableCheck();
for (Entry<String, String> entry : rowList.get(i).entrySet()) {
switch (entry.getKey().trim()) {
case "检查编号":
//一堆业务处理
case "数据库":
//一堆业务处理
case "表":
//一堆业务处理
case "限制条件":
//一堆业务处理
case "检查规则":
//一堆业务处理
case "参数1":
//一堆业务处理
case "参数2":
//一堆业务处理
case "参数3":
//一堆业务处理
case "参数4":
//一堆业务处理
}
}
data.add(dtc);
} 注:原先的代码过于丑陋,所以用了我司封装的方法,将Excel内容读取到一个list中,再循环读取,可以看到代码依然冗长

  这样做有一个问题,如果Excel模板变动或是业务逻辑变动,会牵一发而动全身,后端代码都要改,而且这样的代码可维护性极差,典型的面向过程编程。

  于是,趁着周末,借助策略模式与工厂模式的思想,赶紧重构了代码。


二、重构

  代码中重复的操作是频繁的根据Excel单元格名称去switch不同的处理逻辑,那我们把它抽离出来,即

  

 /**
* 解析Excel数据
* @Author Cone
* @Date 2019/12/7 12:39
*/
public interface dealExcel { void deal(Map.Entry<String, String> entry, DtTableCheck dtc);
}

  传入map中的一个要素,和需要操作的entity,具体的业务处理由不同的实现类去做。

  接下来我们写一个工厂,用来返回不同的实现类:

  

 /**
* @Author Cone
* @Date 2019/12/7 12:49
*/
public class dealFactory { private static Map<String, dealExcel> dealMaps = Maps.newConcurrentMap(); public static dealExcel create(String name) {
return dealMaps.get(name);
} public static void register(String name, dealExcel de) {
dealMaps.put(name, de);
} }

  dealMaps用来保存字段名称(比如检查编号、数据库、表等)和对应的操作实现类,create()方法根据传入的字段名称返回对应的实现类,register()方法则将字段名称与实现类保存到dealMaps中供我们调用。

  这样听起来好像没什么问题,但是我什么时候注册这个实现类到dealMaps中去呢?我们以一个实现类来举例:

  

 /**
* 处理限制条件字段
* @Author Cone
* @Date 2019/12/7 13:16
*/
@Service
public class dealQueryCondition implements dealExcel, InitializingBean {
@Override
public void deal(Map.Entry<String, String> entry, DtTableCheck dtc) {
dtc.setQueryCondition(null == entry.getValue() ? null : entry.getValue().trim());
} @Override
public void afterPropertiesSet() throws Exception {
dealFactory.register("限制条件", this);
}
}

  这个实现类用来处理 Excel中 “限制条件”这一字段,我们在deal()方法中去完成具体的处理逻辑。接下来重点来了,可以看到,这个类还实现了一个接口,即InitializingBean,它是Spring提供的,这个接口里面有一个方法afterPropertiesSet(),用来做属性初始化后的相关操作,凡是继承该接口的类,在bean的属性初始化后,都会执行该方法,我们这里将实现类注册进去。

  接下来就很简单了,只需要根据业务去完成实现类即可。这样改造完后,程序的调用是这样的:

  

 List<Map<String, String>> rowList = ExcelHelper.readExcelSheet(file.getPath());
if (CollectionUtils.isNotEmpty(rowList)) { for (int i = 0; i < rowList.size(); i++) {
DtTableCheck dtc = new DtTableCheck();
for (Entry<String, String> entry : rowList.get(i).entrySet()) {
dealExcel de = dealFactory.create(entry.getKey());
de.deal(entry, dtc);
} } }

  rowList即为Excel中的数据,数据按行存入list,每一行的数据被放入map中,类似这样:

  

 [
"检查编号":value,
"数据库":value,
"限制条件":value
]

  改造后的效果不用我多说了。


三、结语

  我之所以要改造原有代码是因为这个需求在不断变化,模板也在调整,但是如果Excel本来就2,3个字段,或者业务变动不大,那我觉得就没有必要做改造了,改造成本,开发效率需要自己去权衡。运用设计模式应该让代码更好维护,而不是更糟,对吧。

月下无限连?拒绝无休止switch!的更多相关文章

  1. 【Java框架型项目从入门到装逼】第二节 - Spring框架 AOP的丧心病狂解说,你喜欢露娜的月下无限连吗?

    继续上一节的内容,多几个jar包: aop技术是面向切面编程思想,作为OOP的延续思想添加到企业开发中,用于弥补OOP开发过程中的缺陷而提出的编程思想.AOP底层也是面向对象:只不过面向的不是普通的O ...

  2. 一个可无限伸缩且无ABA问题的无锁队列

    关于无锁队列,详细的介绍请参考陈硕先生的<无锁队列的实现>一文.然进一步,如何实现一个不限node数目即能够无限伸缩的无锁队列,即是本文的要旨. 无锁队列有两种实现形式,分别是数组与链表. ...

  3. 2020年Android开发市场真的饱和了吗?

    公司在杭州,根据我的不客观数据体验来看,最饱和的是iOS,同样发布一个职位iOS是其他技术岗位10倍的投递量. 当然Android作为一个已经市场化十余年的技术门类,它必然早已经是成熟常态.这样的技术 ...

  4. Android开发还不会这些?如何面试拿高薪!

    我所接触的Android开发者,百分之九十五以上 都遇到了以下几点致命弱点! 如果这些问题也是阻止你升职加薪,跳槽大厂的阻碍. 那么我确信可以帮你突破瓶颈! 群内有许多来自一线的技术大牛,也有在小厂或 ...

  5. 做Android开发,你后悔过吗?

    有同学跟我说,编程太难了,总是有学不完的技术.框架,新技术也层出不穷,马上三十了,还有各种学不完的东西,后悔做程序员了 编程对我来讲,还难吗 我主业是做Android的. 我刚学编程的时候,觉得难点在 ...

  6. 大厂需要什么样的 Android 开发?

    前言 昨天和一个百度的朋友闲聊,他说根据最近招聘 Android工程师的经验来看,大部分候选人在工作 3 年的时候基本都会遇上一道难过的坎. 为啥这么说呢? 因为工作一段时间之后,大部分工程师都已经完 ...

  7. 收到字节月薪35k Offer,揭秘面试流程及考点

    前段时间,有个朋友又出去面试了,这次他面试目标比较清晰,面的都是业务量大.业务比较核心的部门.前前后后去了不少公司,几家大厂里,他说给他印象最深的是字节. ![](https://upload-ima ...

  8. 我的大学Android开发学习之路——从开始到微信/支付宝/抖音Offer

    前言 笔者2016年高考考入华中科技大学计算机科学与技术专业. 2017年底(大二寒假)拿到今日头条(字节跳动)深圳研发中心Android开发实习生Offer,在深圳研发中心实习至2018年3月. 2 ...

  9. Android太太太太太卷了,累了

    我们聊到互联网行业的时候,一个不可避免的话题就是"内卷",而在程序员这个群体中,Android,绝对是卷得最厉害的. 毕竟前几年Android兴起的时候,入门门槛低,培训机构培养了 ...

随机推荐

  1. [考试反思]0901NOIP模拟测试34:游离

    又是放假回来的收心考.幸而熬了夜回来也不至于很困(虽说第二天早上困成狗...) 说分数吧: skyhAK300,后面有220,220,220,190,190,180 我170,排第8.凑合,其实不太满 ...

  2. [考试反思]NOIP模拟测试19:洗礼

    []260 []230[]210 []200[8]170[9]160 这套题一般,数据很弱,T1T2暴力都能A,而且都是一些思维题,想不到就爆0. 原因不明,很多一直很强的人在这一次滑铁卢了,于是我个 ...

  3. 参与国际化项目需遵循的java命名规范

    笔者最近帮助一些朋友应聘远程工作(一般都是一些国外的项目),国外的项目负责人一般都会要求提供github账号或者一些源代码,很多朋友在这一关就被筛选掉了,其中不乏一些我认为技术非常厉害的行业大牛,他们 ...

  4. 爬虫之request库主要解析---参照慕课北理工嵩天

    kv = {'key1':'value1','key2':'value2'} r = requests.request (' GET' , 'http://python123.io/ws' , par ...

  5. 路径操作OS模块和Path类(全)一篇够用!

    路径操作 路径操作模块 os模块 os属性 os.name # windows是nt, linux是posix os.uname() # *nix支持 sys.platform #sys模块的属性, ...

  6. 关于Python中的yield的理解

    生成器:yield表达式构成的函数就是生成器:每一个生成器都是一个迭代器(但是迭代器不一定是生成器).return就是迭代器: yield的功能类似于return,不同之处在于它返回的是生成器. 什么 ...

  7. centos6的JDK安装

    1. 通过如下命令查看当前操作系统是否存在JDK rpm -qa | grep java 如果出现以下内容说明你的操作系统存在jdk 2.那么依次通过如下命令进行删除它 rpm -e - -nodep ...

  8. Vue的指令以及组件化开发

    一. 自定义指令 如何: 1. 创建指令 Vue.directive("指令名",{ inserted(elem){//指令所在的元素被加载到DOM树上后自动执行指令 //elem ...

  9. Springboot中的缓存Cache和CacheManager原理介绍

    背景理解 什么是缓存,为什么要用缓存 程序运行中,在内存保持一定时间不变的数据就是缓存.简单到写一个Map,里面放着一些key,value数据,就已经是个缓存了 所以缓存并不是什么高大上的技术,只是个 ...

  10. 130道ASP.NET面试题(二)

    71.什么是反射?答:动态获取程序集信息 72.用Singleton如何写设计模式答:static属性里面new ,构造函数private 73.什么是Application Pool?答:Web应用 ...