月下无限连?拒绝无休止switch!
拒绝无休止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!的更多相关文章
- 【Java框架型项目从入门到装逼】第二节 - Spring框架 AOP的丧心病狂解说,你喜欢露娜的月下无限连吗?
继续上一节的内容,多几个jar包: aop技术是面向切面编程思想,作为OOP的延续思想添加到企业开发中,用于弥补OOP开发过程中的缺陷而提出的编程思想.AOP底层也是面向对象:只不过面向的不是普通的O ...
- 一个可无限伸缩且无ABA问题的无锁队列
关于无锁队列,详细的介绍请参考陈硕先生的<无锁队列的实现>一文.然进一步,如何实现一个不限node数目即能够无限伸缩的无锁队列,即是本文的要旨. 无锁队列有两种实现形式,分别是数组与链表. ...
- 2020年Android开发市场真的饱和了吗?
公司在杭州,根据我的不客观数据体验来看,最饱和的是iOS,同样发布一个职位iOS是其他技术岗位10倍的投递量. 当然Android作为一个已经市场化十余年的技术门类,它必然早已经是成熟常态.这样的技术 ...
- Android开发还不会这些?如何面试拿高薪!
我所接触的Android开发者,百分之九十五以上 都遇到了以下几点致命弱点! 如果这些问题也是阻止你升职加薪,跳槽大厂的阻碍. 那么我确信可以帮你突破瓶颈! 群内有许多来自一线的技术大牛,也有在小厂或 ...
- 做Android开发,你后悔过吗?
有同学跟我说,编程太难了,总是有学不完的技术.框架,新技术也层出不穷,马上三十了,还有各种学不完的东西,后悔做程序员了 编程对我来讲,还难吗 我主业是做Android的. 我刚学编程的时候,觉得难点在 ...
- 大厂需要什么样的 Android 开发?
前言 昨天和一个百度的朋友闲聊,他说根据最近招聘 Android工程师的经验来看,大部分候选人在工作 3 年的时候基本都会遇上一道难过的坎. 为啥这么说呢? 因为工作一段时间之后,大部分工程师都已经完 ...
- 收到字节月薪35k Offer,揭秘面试流程及考点
前段时间,有个朋友又出去面试了,这次他面试目标比较清晰,面的都是业务量大.业务比较核心的部门.前前后后去了不少公司,几家大厂里,他说给他印象最深的是字节. 拿到今日头条(字节跳动)深圳研发中心Android开发实习生Offer,在深圳研发中心实习至2018年3月. 2 ...
- Android太太太太太卷了,累了
我们聊到互联网行业的时候,一个不可避免的话题就是"内卷",而在程序员这个群体中,Android,绝对是卷得最厉害的. 毕竟前几年Android兴起的时候,入门门槛低,培训机构培养了 ...
随机推荐
- 学习笔记27_Action方法技巧
*在Action方法中,会存在重载问题,名字冲突就会报错,使用 [HttpPost]//只接受Post请求,且级别较高 public ActionResult Edit(..){} *在Action方 ...
- 『题解』洛谷P5015 标题统计
题意描述 给你一个字符串,求所有字符的总数. 字符只包含数字,大小写字母. 分析 字符串的长度还是\(\le5\)的. 直接枚举就可以了. AC代码: NOIP官方标准程序是这样的 #include ...
- 代码托管服务平台GitHub
GitHub 可以托管各种 git 库,并提供一个 Web 界面,但与其它像 SourceForge 或 Google Code 这样的服务不同,GitHub 的独特卖点在于从另外一个项目进行分支的简 ...
- C语言程序设计100例之(6):数字反转
例6 数字反转 题目描述 给定一个整数,请将该数各个位上数字反转得到一个新数.新数也应满足整数的常见形式,即除非给定的原数为零,否则反转后得到的新数的最高位数字不应为零(参见样例2). 输入格式 ...
- vue使用一些外部插件及样式的配置
一.配置全局css及js样式 1.首先将事先写好的css文件及js文件放在src文件目录下的assets文件下 2.在main.js文件输上图右边两个红色框的代码 二.配置全局jQuery及boots ...
- ubuntu开机自启动服务
ubuntu下一个用来管理开机自启动服务的程序,今天在ss vps上安装时老是提示这个错误,百度后,下面的这个方法可行: vi /etc/apt/source.list 输入i,进入Insert模式 ...
- 理解clientWidth,offsetWidth,clientLeft,offsetLeft,clientX,offsetX,pageX,screenX
1. clientWidth:表示元素的内部宽度,以像素计.该属性包括内边距,但不包括垂直滚动条(如果有).边框和外边距.(clientWidth = width + padding) 2. offs ...
- nyoj 1071-不可以!(a*b + fabs(a*b))
1071-不可以! 内存限制:64MB 时间限制:1000ms 特判: No 通过数:10 提交数:18 难度:1 题目描述: 判断:两个数x.y的正负性. 要求:不可以使用比较运算符,即" ...
- 【前端知识体系-JS相关】JS-Web-API总结
2.1 DOM操作 2.1.1 DOM的本质是什么? <!-- DOM树:二叉树 --> /* <?xml version="1.0" encoding=&quo ...
- 简单说说基于JWT的token认证方式
一.什么是认证 好多人不知道什么是认证,认证,其实就是服务端确认用户身份.Http协议是无状态的,客户端发送一条请求,服务端返回一条响应,二者就算做成一单买卖,一拍两散.在很久以前,互联网所能提供的服 ...