文档章节

重构之重与敏捷之轻---身份证号重构回顾

予沁安
 予沁安
发布于 2013/01/25 04:31
字数 1508
阅读 2303
收藏 36

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

寻找重构的案例

重构的案例不好选取,我们自己实际的项目当然有不少重构的情况,却不适合作为文章阐述出来。并不是因为保密的考量,而是业务本身的内容太复杂。当然,这个复杂是相对的,对短短一篇文章来说,那怕是最小一部分的业务逻辑拿出来,也显容量不够。而且,过多的阐述业务逻辑,导致喧宾夺主,掩盖了重构的注意力。所以,要选取一个大家都熟悉的东西,身份证号恰恰中了我第一个要求。

即然是重构,必然要有个原始的版本,而且,要完成了实际的功能。开源中国的代码分享也刚好为我提供了一个资源库。代码分享这个平台,真是太理想了,代码规模不大不小,每一个分享又有一个明确的目标功能。
看起来,确实是个金矿。可是随着深入的搜索查看,能进入我目标范围的却是寥寥无几。大部分代码只是粘合剂,把外部库的调用综合起来,完成一个任务而已。还有些代码,方法体太大,而代码却是简单重复,似乎重构的必要,却未能展现出重构该有的不同侧面,而且也有前面所提到的毛病,是粘合剂代码块。
(本文版权属于© 2012 - 2013 予沁安

而当我看到身份证这三个字,才眼睛一亮,看似简单的身份征号包括了太多内容:

  1. 它是一个典型业务域的Value Object(不要与C#语法概念的Value Object混淆),我们自己的系统中,刚好也有做一个身份证号值对象的想法。之前我们已经作一个月份对象(YearMonth),非常好用,但是,因为功能多代码量大,不适合作短篇。
  2. 它没有对外部库的依赖。不是说,我只能对这种独立的代码重构,而是限于篇幅和重点突出的考虑。
  3. 它的业务逻辑很大众化,谁没有身份证呢?
  4. 分享代码已经把足够的业务逻辑包含进起,我所做的就是保持这个不变全力集中在重构上。再完美不过的重构案例了。

敏捷的方式重构和作文


让子弹飞

定下了目标,当开始做的时候,满脑子都是想法。原代码是Java,要改成C#; getXX可以用属性方式,更为简捷;既然是Value Object,似乎用Struct比用Glass更合适;作为Value,它应该是个不变类(Immutable),因此不应该动态解析,在构造器中解析,更为恰当; Validation的实现也不太合适……
是的,像我这样资深的敏捷实践者,在第一时间仍有这种冲动,太多想法马上实现的冲动。这其实是人的一种天性,没关系,我就让思维的子弹先飞一会儿。
子弹乱飞之后的寂静,我想到的第一件事情就是补测试。说到测试,我用MSpec曾屡屡想为MSpec做个入门介绍,却一直未能成文,而直接使用MSpec的博文我却已经写了不少, 大家就在实际用例中学习Machine.Specification吧。
说是补测试,其实从Java到C#的编泽错误修改已经开始了不少改动。测试这一块是原代码完全缺失,补上这个,可以说是重构的一部分。

迭代一:

准备工作做了不少,到最后,真正测试只写了一个GetAddress()。而这成为了我的第一天。第一个测试成为我第一天的目标,围绕这个目标,我放弃一切与此无关的工作,特别是之前子弹乱飞的内容。

迭代二:

第二天,要做的事情一下子非常明确,按部就班的把其它的功能测试一一补全:生日,性别等等。几乎不太用脑子,有时候,事情就是这样,有波涛汹涌,有风平浪静,唯有测试是船舵。
从测试的条数来看,第二天进展很快。写出来的内容也显丰富。

迭代三:

第三天的进展就顺利多了。把各个功能测试一一补全通过,如生日,性别和验证。其中有个小插曲,验证逻辑提炼成独立的类。总结起来没有什么好说的,重构本身却有看头。

迭代四:

到了第四天,才真正开始做我想要做的事情,整理逻辑,清理代码。再加上代码覆盖工具DotCover的帮助,VS的复杂度分析,从另一个侧面对重构效果加以验证。其实应该在重构之前也分析一下代码,两相比较一下,效果会好很多。

从此,xx和xx过上了幸福的生活......

我的博文算是结束了,可是作为代码的改进,其实并没有结束,甚至我最开始的想法,有一部分都还没有完成,如struct。我还丢掉了一部分业务,如15位号码转换18位。这是作为重构的展示已经足够。最重要的是,我已经创立了一个健壮的<测试-实现>对,这个基础上你可以继续完善。

代码本身的技术含量并不多,但重构的流程,任务细分,小步前进的理念,却表达的非常充分。作为体验,如果你能按照我走过的流程,再踏踏实实走一遍,会有完全不同的感觉。敏捷是实践,重构是实践,唯有实践才能体验实践。(本文版权属于© 2012 - 2013 予沁安 | 转载请注明作者和出处

© 著作权归作者所有

予沁安

予沁安

粉丝 98
博文 23
码字总数 31905
作品 3
其他
架构师
私信 提问
加载中

评论(8)

予沁安
予沁安 博主

引用来自“jqbmaster”的评论

颇有感触

哪一方面?
JqbR001
JqbR001
颇有感触
予沁安
予沁安 博主

引用来自“不争”的评论

没看懂

:(
予沁安
予沁安 博主

引用来自“严瑾”的评论

码字不易,支了个持

:)
Duziee
Duziee
码字不易,支了个持
不争
没看懂
予沁安
予沁安 博主

引用来自“疯狂的流浪”的评论

不错的分析,感谢楼主

也感谢你的留言,虽取手之劳,给我支持无限。
疯狂的流浪
疯狂的流浪
不错的分析,感谢楼主
文章资源汇集

架构 我眼中的Visual Studio 2010架构工具 基于消息与.NET Remoting的分布式架构 设计 领域驱动设计实践 解除具体依赖的技术 期待的接口 软件隐喻的本质与模式 虚方法的使用 依赖之殇 敏捷 ...

wayfarer
2010/12/29
0
0
「修改软件的艺术」 读书笔记

date: 2017-10-13 17:59:11 title: 「修改软件的艺术」 读书笔记 百度脑图 - 修改软件的艺术: http://naotu.baidu.com/file/3300eebf1014c10fd4d1a96ad6cf65ac?token=ff8bec2d896c0c61 图灵社......

daydaygo
2017/10/20
0
0
JeeSpringCloud v3.1.1 发布,互联网云快速开发平台

JeeSpringCloud,一款免费开源的JAVA互联网云快速开发平台,微服务分布式代码生成的敏捷开发系统架构。项目代码简洁,注释丰富,上手容易,还同时集中分布式、微服务,同时包含许多基础模块和监控...

suncos
2018/11/12
1K
2
闲谈简单设计(KISS)疑惑

忙碌了一年了项目又到了交付了,虽然项目能成功上线(因为还有维护支持的团队)。但是个人从技术上看,这是一个不那么成功的项目,因为后期艰难的修复bug,添加feature。这与简单设计有什么关...

zting科技
2017/01/10
0
0
JeeSpringCloud v3.0 发布,互联网云快速开发平台

JeeSpringCloud,一款免费开源的JAVA互联网云快速开发平台,微服务分布式代码生成的敏捷开发系统架构。项目代码简洁,注释丰富,上手容易,还同时集中分布式、微服务,同时包含许多基础模块和监控...

suncos
2018/10/26
2.5K
6

没有更多内容

加载失败,请刷新页面

加载更多

学习记录 互联网项目---3(Ribben优化)

3.3 负载均衡策略 {服务名称}.ribbon.NFLoadBalancerRuleClassName=具体策略 service:#服务名 ribbon: NFLoadBalancerRuleClassName : com.netflix.loadbalancer.RandomRule ......

Pole丶逐
30分钟前
3
0
redis - 的线程模型

redis 的线程模型 redis 内部使用文件事件处理器 file event handler,这个文件事件处理器是单线程的,所以 redis 才叫做单线程的模型。它采用 IO 多路复用机制同时监听多个 socket,根据 so...

Canaan_
31分钟前
7
0
IT兄弟连 HTML5教程 使用盒子模型的浮动布局

虽然使用绝对定位可以实现页面布局,但由于调整某个盒子模型时其他盒子模型的位置并不会跟着改变,所以并不是布局的首选方式。而使用浮动的盒子模型可以向左或向右移动,直到它的外边缘碰到包...

老码农的一亩三分地
31分钟前
3
0
ubuntu上编译和使用easy_profiler对C++程序进行性能分析

本文首发于个人博客https://kezunlin.me/post/91b7cf13/,欢迎阅读最新内容! tutorial to compile and use esay profiler with c++ on ubuntu 16.04 <!--more--> Guide compile git clone h......

kezunlin
53分钟前
5
0
nginx master-worker进程工作原理

nginx的master-worker进程模型是其能够高性能的处理用户请求的原因之一,而且这里的每个worker进程都只会启动一个线程来处理用户请求。通常我们会将worker进程的数量设置得与我们的CPU数量一...

爱宝贝丶
今天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部