比如说你的老板说,你那个系统重新做一下,要增加一个需求。你打开一份源代码,完全不知所云,你吐槽着谁能写出如此不堪入目的代码,于是决定查看版本记录,把这个家伙找出来鄙视一下。然后你在提交历史里看到了自己的名字... 恭喜你。程序员通常在几个月甚至几个星期之后就认不出自己写的代码。 随着增加新特性或需求变更,代码会变得越来越难以维护。软件开发的十二条原则中有一条是:我们始终拥抱需求变化,哪怕是在软件开发的后期。为了达到这种状态,就要在开发过程中持续地优化代码。而重构这项技术则为我们提供了一种更可控的方式来优化代码。
1、重构是什么
重构通常指的是【代码重构】,在日常工作中,我们把重构既作为名词又作为动词来使用,作为名词时,它的意思是:对软件内部结构的一种调整,目的是在不改变软件可观察行为的前提下,提高其可理解性,降低其修改成本。重构本质上是一种代码整理技术,这项技术使得代码整理的效率更高,风险更小。
2、如何做
接下来从几个方面来说说如何做重构:
什么时候开始
什么时候停止
前提条件
重构的过程
2.1、什么时候开始
重构不应该是一个单独的环节,应该融入到开发软件编写代码的过程中,就像使用版本控制系统提交代码一样,是一个必须做的动作。你不会跟项目经理说,我需要申请一段时间来提交代码,所以也不用说服项目经理给你时间重构。你可以在开发新功能,修复 Bug 的过程中就把重构做了,除了你的程序员同伴,没有人知道你做了什么。而他们会认为你做了一件了不起的事情,因为你让代码结构更清晰了,以后添加新特性就会更容易,而 Bug 也无处藏身。
如果你采用 TDD 的方式(测试驱动开发),那重构已完全融入到了开发过程中。如果没有采用 TDD,通常有四个时机可以考虑要不要重构:
如果有段代码让你修改起来很不舒服,前两次还可以忍耐,第三次就无需再忍了,果断操起 IDE 重构之。因为出现了三次修改,说明有很大概率以后还会修改,这是一笔划算的投资。
有时候我们发现要添加一个新功能很难,我们可以对代码做一些重构,让添加新功能变得容易。
在修 Bug 时,我们大部分的时间会花在定位 Bug 上,为什么这么难以找到呢?多半是因为代码结构不清晰,如果代码在同一抽象层次上,每个方法都在 10 行以内,每个方法名和变量名都能清晰地表达意图,Bug 就再无藏身之处。所以通过重构代码,可以让 Bug 自动浮现出来。
在 Code Review 时,其他程序员会提出代码修改的意见,记录下来,等 Code Review 结束之后就可以开始重构了。
2.2、什么时候停止
重构到什么时候,我们就认为可以停止了呢?标准是「简单设计」的四条原则:
通过所有测试
没有重复
表达意图
最少化程序元素(类,接口,变量,方法等)
2.3、重构的过程
重构的基本步骤是:
测试保护如果没有测试代码,就要先添加测试代码。如果有测试代码,先运行一下,保证在开始重构之前,测试是运行通过的。还要认真审查一下测试代码,看是否有遗漏一些场景,有遗漏的话要补充遗漏的测试场景。
识别味道怎么知道哪些代码需要重构呢?首先,代码是可以工作的,我们并不能说它有问题,但它又不像我们期望的那样好。这些需要自行判断,而直觉的形成有两种方法,一是随着编码经验的增多自然形成,另一种更快的方式是大量阅读优秀的开源代码,提高自己的代码审美。
采用手法
识别到味道之后,就要知道有什么对应的手法可以消除这个味道,执行完这个手法之后代码会变成什么样子。列举了 66 个常用手法,可以分为六大类:
*函数
搬移特性
组织数据
简化条件
简化调用
处理概括
运行测试
在采用了手法修改代码之后,就要执行测试以确保真的没有改变软件的行为。做了重构之后测试会失败,但实现并没有问题,需要修改测试代码让它成功。这就说明测试写的不合理,给重构带来了负担,所以测试的粒度要把握好,太细的粒度就会增加维护成本。比如有些人会给每个私有方法都写单元测试,那有可能采用「内联函数」这个手法之后这个方法就不存在了,就需要修改测试。
提交代码
最后,如果你采用了一个比较复杂的手法,或者即将采用一个复杂的手法,最好先提交一下代码,以保证出现意外后能快速回滚,避免浪费时间。重构要采取「小步快跑」的原则,尽量采用安全的手法,让测试一直处于通过的状态。 从低级的坏味道开始,消除低级味道之后,高级味道才会浮现出来。
3、重构与设计的关系
在没有重构这个技术之前,广泛采用的是 Big Front Design,在开始编码之前要进行非常详细的设计,考虑应对未来出现的各种变化。而有了重构技术之后,前期设计的压力就小了,毕竟可以随时通过重构来改善设计,应对变化。所以你大可不必一上来就应用《设计模式》把代码搞复杂,先用简单的实现满足当前需求即可。等变化真正来临时,再通过重构技术调整设计,模式给我们提供了一个方向,但并不是最终目标。还记得简单设计的四条原则吗?通过测试,没有重复,表达意图,最少元素。只要最终的代码符合好的原则,干净整洁没有坏味道,管它符不符合某个模式呢?
4、大型遗留系统的重构
对于代码上百万,千万行的遗留系统,怎么重构呢?满地都是坏味道,一点点去重构,什么时候是个头?这时,选择哪些代码来重构就非常重要,影响到投资回报。如果对代码进行分类,将会得出几种类型:
不会被执行的烂代码
运行稳定,基本不会改动的烂代码
经常发现 Bug 的烂代码
经常需要变更的烂代码
不会被执行的代码,直接删除就好了。运行稳定的又不需要改动的,动它反而可能引入风险,当然,在时间充裕的情况下,还是可以重构的。真正有价值,值得重构的,投入产出比最高的,是经常出问题和经常会有需求变更的烂代码。优化了这部分代码,可以减少 Bug 和进行需求变更的时间。
5、总结
我们来回顾一下:
5.1、为什么要重构?
为了让软件始终可以维护,保证开发效率。
5.2什么是重构?
一种以可控的方式整理代码的技术,在不改变软件可观察行为的前提下改善其内部结构。
5.3、什么时候开始?
事不过三,添加功能,修复 Bug,代码评审时。
5.4、什么时候停止?
重构到符合简单设计四条原则的 Clean Code。
5.5、前提条件
测试保护,版本控制。
5.6、重构的过程
运行测试,识别味道(常见的 22 种),采用手法(66 个),运行测试,提交代码。
5.7、重构与设计的关系
有了重构技术,我们不用在前期做非常详细的设计,做适当的设计,然后通过重构让设计浮现出来。不用在乎软件是否符合模式,只要符合原则即可。
Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved