重读《重构 2》- 引入参数对象
6.7 变量改名(Rename Variable)
变量命名不是一视同仁,使用范围越广,名字的好坏就越重要。
最小范围,如 lambda 表达式,一般用单个字母,a、i、n、x 等即可;
只在函数内部作用的临时变量,能表达值的意思即可;
需要当函数参数或返回值当变量,要能准确表达其意;
已发布变量,是需要文档化的,需要长期稳定,不能随便修改,如果要修改,可以使用「封装变量」。
6.8 引入参数对象(Introduce Parameter Object)
将数据组织成结构是一件有价值的事,因为这让数据项之间的关系变得明晰。
这里指的对象就是 DDD 里面的 VO:https://en.wikipedia.org/wiki/Value_object
但这项重构真正的意义在于,它会催生代码中更深层次的改变。一旦识别出新的数据结构,我就可以重组程序的行为来使用这些结构。我会创建出函数来捕捉围绕这些数据的共用行为——可能只是一组共用的函数,也可能用一个类把数据结构与使用数据的函数组合起来。这个过程会改变代码的概念图景,将这些数据结构提升为新的抽象概念,可以帮助我更好地理解问题域。果真如此,这个重构过程会产生惊人强大的效用——但如果不用引入参数对象开启这个过程,后面的一切都不会发生。
-- 这一段话也表明了 VO 的存在价值。
POJO 里的 VO/BO/DO/DTO 和 DDD 里的 VO 虽然是 2 个不同体系下的定义,但所表达的概念是类似的:
1、封装原始类型:int/string,增强表达力;
2、增加抽象层次,让高层表达更简洁;
3、借助丰富的类型,让编译系统辅助检查人为错误。
定义类型的作用:
1、检测错误,让错误从运行时提前到编译时;理想情况下,编译通过就能确保没有 bug,如 Haskell、Rust 基本能做到这个程度;
2、方便重构,改名、改定义都能触发编译错误,让重构高效;即设计变更时要让编译器能检测出来;
3、抽象,提高设计稳定性,要让使用者保持稳定,就不能直接依赖细节,需要增加类型抽象;
4、文档,Types are also useful when reading programs.
5、安全,safe languages can be defined as ones that make it impossible to shoot yourself in the foot while programming. 简单说就是:让犯错变难;
6、高效,proving statically 让运行时减少 dynamic checks,自然高效;
7、可移植性,同一份设计,用 c、java、js/ts 实现,不会感觉到别扭。
6.8 节这个例子包含了重构的精髓,大家要精读。
重构的好处是可以零起步,刚开始大家写的代码都不是太好,然后按照重构手册找对应的方法老操作,就能起到好的效果。
如果你是熟手,当然不屑里面繁琐的步骤;但如果是新手,重构就是很好的启蒙材料:一来培养了好的习惯,二来也能解决工作中实际的问题。
版权声明: 本文为 InfoQ 作者【顿晓】的原创文章。
原文链接:【http://xie.infoq.cn/article/18cbd4e3f6e4e9932f650bdb2】。文章转载请联系作者。
评论