拒绝无休止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. C++学习笔记7_多态

    1. 类与类之间的关系class A{ public: int a; void funcA() {}}包含: class B { public: void funcB(){} A a; }//如果类B ...

  2. 学习笔记11全局处理程序global.asax

    *全局处理程序Clobal.asax只能叫这个名字,不能修改文件名,如果网站没有的话,可以自己添加. *Application[]类似于session,是全局的,Application["k ...

  3. Oracle Dorp 表数据恢复

    利用Oracle 数据回闪机制进行恢复,当一个表被drop掉,表会被放入recyclebin回收站,可通过回收站做表的闪回.表上的索引.约束等同样会被恢复不支持sys/system用户表空间对象,可通 ...

  4. [考试反思]1012csp-s模拟测试70:盘旋

    这套题比较烂... 上来看到T2是原题,一想上一次考试遇到原题就不换,这次应该也是,于是直接开始码,码了一半然后换题了 T1打表找规律或者推式子都不难... T2水的一匹暴力剪枝即可,但是我并不知道数 ...

  5. Linux下基本操作

    强行转Linux,开始以为会很不适应,其实还好,换汤不换药 本文只讲基本操作,足够让你愉快的打代码,想飞上天的自行百度,或找其他大神(友链) Update 6/20:由于写得太烂被学长爆踩了一顿 直接 ...

  6. csps模拟测试 77爆零反思

    题不算太难,可是我还是没考出应有水平. $1h8min$切掉前两道题,然后$T3$想到正解并且码出来了并且过了大样例并且爆零. 没什么好说的,我太自信了,没打对拍? 想到了正解,还不如随便打个暴力分高 ...

  7. 20190630A(贪心)

    题目描述 约翰留下他的N只奶牛上山采木.他离开的时候,她们像往常一样悠闲地在草场里吃草.可是,当他回来的时候,他看到了一幕惨剧:牛们正躲在他的花园里,啃食着他心爱的美丽花朵!为了使接下来花朵的损失最小 ...

  8. css3 preserve-3d 的理解 注意IOS上的兼容

    css3 preserve-3d 的理解 <pre><!DOCTYPE html><html lang="en"> <head> & ...

  9. win7设置docker默认服务端地址

    目录 win7设置docker默认服务端地址 1.开启docker远程访问 2.本地调整 2.1 docker.exe重命名 2.2 添加docker.bat 2.3 添加快速切换功能 3.使用验证 ...

  10. (二十一)golang--字符串中的函数

    golang中ascii对应的字符占一个字节,而汉字占三个字节. (1)统计字符串的长度len (2)字符串遍历,同时处理有中文的问题r:=[]rune(str) (3)字符串转整数:n,err:= ...