做者:Greyhtml
时间:2018-11-25java
原文地址: http://www.javashuo.com/article/p-qdnnwvha-cb.html数据库
以前作的功能, 又有新的需求了,原先的需求是支持某个类型的待办审批,如今是要支持系统全部类型待办的审批,虽然以前的代码写的很匆忙,比较“丑陋”,可是好在未出什么bug,新需求来了之后,我本想乘此机会重构一下本身以前写的比较丑陋的代码,可是由于陆陆续续有插入进来的优先级更高的任务,因此这个新需求一直被hold住,最后有一周的时间来作这个需求,因为要测试的流程比较多,并且建立流程的过程比较费时,为了给测试预留多一些时间,我放弃了重构的念头,先快速实现需求,在保证原有功能和新增需求没有问题的状况下,再一点点重构本身的代码。服务器
有一个Web系统X,用户能够经过这个系统查看本身的待办信息,而且能够用于待办的审批,还有一个咱们作的手机应用Y,Y系统须要支持查看X系统的待办信息并完成审批操做。运维
原需求里面说的待办信息只是某两个类型的待办,实际上这个X系统有不少待办类型,并且每一个类型的处理逻辑,显示元素都是不同的,咱们如今要实现再Y上支持X系统的全部待办类型的审批。工具
为了不上一次返工的问题之一:需求没有梳理清楚。在写代码以前,开发和测试都须要很是了解业务逻辑,因此,在开发以前,我特地申请了一次培训,让运维人员给咱们(我做为开发,还有一位测试人应)讲解一下整个系统的流程,也不须要特别正式的会议室,就几我的在电脑旁边,运维人员从头至尾给咱们整个走一遍流程,有任何疑问都当下提出,当下解决, 解决不了的记录下来,运维人员后去请教实际用户这些问题。补充一点:最了解X系统业务的人固然是使用这个系统的用户,但是这个系统比较特殊的一点是,大部分用户都是领导,咱们几乎不太可能让领导来花时间来给咱们讲整个业务逻辑,只能是当咱们遇到一些实际的业务问题,再去和他们请教。而运维人员,算是除了用户之外,相对比较了解X系统的人了,什么?你说X系统的开发人员?这个系统的开发商已经“跑路”了:)测试
在培训完业务流程后,我尚未急着作开发,而是先让测试人员在X系统上走一遍流程,并把走流程中的一些关键信息(如待办详情,操做按钮,下一步操做选择)截图,一来测试须要了解整个业务流程才知道如何设计测试用例,二来截图也能够给我开发作一些参考,好比须要显示待办详情里面的哪些信息,操做按钮要如何显示,下一步操做要如何处理等。this
测试人员在X系统上走完流程之后,我本身也参考测试人员写的操做步骤和截图,走了一遍流程,算是内心有个底了。设计
X系统有个测试环境,咱们都是在X系统的测试环境中开发和测试的,可是这个环境很不稳定,由于运维人员常常为了排查X系统的问题,会常常把X系统正式环境的数据导入到测试环境,这样咱们在X系统作的数据就会被重置,这就尴尬了,咱们的开发周期是一周,想在这一周保证测试数据稳定是不可能的了,因此,我又作了一件事,找了一个新的服务器,在这个服务器上从新搭建一个X系统的测试环境(包括应用服务器,数据库),总算是解决了这个问题。日志
遇到的另一个问题是,每次X系统中的待办建走到特定节点比较费时,而每一个特定节点须要定制开发,好比咱们的手机应用Y要支持X系统某个待办的第五个环节,那我须要在X系统上建一个待办,而后一步一步走到第五个环节,而后找这个环节须要显示的信息,须要作的操做,很是麻烦,并且一旦我在手机上操做了这个环节(好比审批了),这个环节就跳到了第六个环节了,若是我第五个环节的东西尚未彻底开发完,我又要建一个流程并走到第五个环节,比较麻烦。因此我想了一个办法,就是在走到某个环节的时候,先备份一下数据库,走完这个环节若是想再回去看下的话,直接恢复备份数据库就能够了。
放弃重构想法之后,我开发相对比较谨慎,基本没有改动以前的代码,新的需求都是从新写的代码,并为考虑复用太多以前的代码,虽然几回很想重构,可是仍是忍住了,求稳。
业务逻辑理清了,接下来就是要看懂X系统的源码了,X源码注释也比较少,充斥着相似如下这样的代码:
if(StringUtils.equalsIgnoreCase(subTypeId, "501")){ // do something ... }else if(StringUtils.equalsIgnoreCase(subTypeId, "502")){ // do something ... }else if(StringUtils.equalsIgnoreCase(subTypeId, "601")){ // do something ... }else if(StringUtils.equalsIgnoreCase(subTypeId, "602")){ // do something ... } else if(StringUtils.equalsIgnoreCase(subTypeId, "604")){ // do something ... }
我必须一个一个节点走才知道这里的诸如:"501","604"是什么意思,而后把这里面对应的SQL拿出来分析,看下须要哪些参数,这些参数是如何获取的,并且有些SQL的查询还很复杂,参数不少,我本想直接用正则匹配页面中的这些参数值,后来想一想,仍是不能依赖X系统的页面信息,我都是直接查数据库获取须要的参数,分析SQL和获取查询参数,耗费了巨大的时间,不过事实证实,这样作是对的,我这至关于重作了一遍X系统了。
接下来是设计X系统集成到咱们手机APP系统Y中之后的展现和操做,因为数据都拿到了,我就须要把这些数据转换成咱们手机APP中展现的元素,好比:Table,KeyValue,List,这些东西实际上没有一个统一的标准,咱们就把详情中比较关键的一些信息显示出来,至因而显示成Table仍是KeyValue,这个没有严格的标准,用户彷佛不太关注内容的排版,只要是显示了必要信息,简单明了,就足够了,因此这部分”设计“,就按照我本身的想法来作了。
接下来是审批操做,审批操做比较麻烦的一点是,你必须彻底了解,点击这个待办的操做按钮背后的全部逻辑,由于咱们是要集成待办的操做,因此咱们实现的逻辑要和X系统如出一辙,最简单粗暴的方案固然是模拟X系统的操做,好比用一些爬虫工具模拟点击操做的按钮,这样咱们就彻底不须要了解X系统的操做流程了,可是这并不保险,仍是由于上一次返工给我带来的教训:万一操做的元素变更了一下,咱们的操做就彻底失效了。因此此次我仍是选择直接理解操做背后的逻辑,说白了就是把操做对应的Ajax请求一个一个看懂并找到对应的参数值,而后发一个如出一辙的Ajax操做,固然X系统点击操做还不是简单的拿一些现有的参数发请求,有一些是页面中的js拼装的一些数据,这部分也要彻底理解并彻底移植过来,一旦有一些操做没有移植过来,若是待办审批出了问题,是很是严重的,由于这些待办涉及比较重要的招投标流程,流程涉及的金额也是很大的。
我回忆了一下,真正写代码的时间实际上很少,花时间最多的是看X系统的源码,和熟悉X系统的业务流程。
最后是测试,由于要在手机APP上测试流程,可是咱们本身的工号下面都没有对应的待办信息,须要登陆相应的领导的帐户才能够拿到待办信息,虽然是测试环境,可是咱们手机APP是不会用用户的信息去登陆测试的,由于登陆后,用户的全部信息咱们均可以看到了,解决办法就是,在获取用户待办的时候,咱们只拿用户的X系统的待办,其余信息不获取,因此获取X系统的待办逻辑的代码,加了这么一小段逻辑,大概意思就是以下:
this.工号 = 获取登陆人的工号(); // 登陆人是本身人 Map<String,String> changedInfo = newHashMap(); changedInfo.put("本身人的工号1","有待办的人的工号1"); changedInfo.put("本身人的工号2","有待办的人的工号2"); changedInfo.put("本身人的工号3","有待办的人的工号3"); this.工号 = changedInfo.get(this.工号); List todoList = 经过工号获取某人X系统的待办信息(this.工号);
这个需求开发并上线已经两周了,我监控了一段时间运行日志,暂时未发现问题,本次整个开发过程,吸收了上一次返工的教训,为我之后的开发工做也积累了一些新的经验,谨以这两篇博客(本篇博客, 上一篇博客)做为一个记录,也但愿能够分享给有须要的人。