为什么收拾屋子?
住酒店,有服务生帮我们收拾房间,在家需要自己收拾,因为自己还要住很长时间。屋子干净了,还是有好处的,东西就好找了,哪些东西放的位置不对,也更容易识别出来。
我们看看《[重构][refactor]》中Martin Fowler对“重构”的定义:
名词定义:对软件内部结构的一种调整,目的是在不改变软件可观察行为的前提下,提高其可理解性,降低其修改成本。
定义中给出了重构的两个目的(收益):
- 提高可理解性
- 降低修改成本
代码编写完成后,自己或者他人还会维护较长一段时间。重构,是期望代码可以更多的被复用,有更长的服役时间。
如何收拾屋子?
根据屋子的布置(结构),每件物品都有它应该放置的位置,发现不在位置上,就调整调整。
重构是对软件内部结构的一种调整。好的软件在满足系统功能正确性、性能等要素同时,还需考虑软件的扩展性、伸缩性和可读性。所以它应该是有架构的,体现为横向切分的不同层次和纵向切分的不同模块,及更细粒度的类、方法、函数。重构就是根据软件本身应该的结构,对代码元素进行调整,放到合适的位置。
什么时候收拾?
发现屋子脏了、乱了就收拾收拾,工作忙,就周末收拾,工作轻松些就每天顺手收拾。但是房子脏,那是欠的债,迟早需要还的。
伴随着开发的过程,重构应该是个习惯,发现代码有坏味道了,就及时消除掉。交付压力太大时,就稍微缓缓,等稍能喘口气,就赶紧把债还掉,不然积少成多,可能就很难收拾了。
Martin Fowler给出了四个重构时机:
- 产生重复代码时,
- 新增功能之前
- 修改故障之前
- 代码走查之后
Kent Beck提出的XP(eXtreme Programming)中,TDD实践更是把重构作为开发过程中的一部分:
大扫除
逢年过节,你会来个大扫除,彻底把屋子调整调整。
时间久了,新人多了,交付压力大了,代码难免会产生一些腐化,这些可以通过集中重构,彻底清洗清洗。
装修
发现房间布置,格调有点跟不上时代,需要整的大些,就是装修了。要看自己有没有地儿住,有没有时间折腾。
当系统新增功能改动很大;当系统性能成为瓶颈,无法忍受;当代码穿着一层层补丁贴成的外衣,仍到处漏风时,此时缝缝补补此时已无济于事,需要更大的调整,才能根除这些问题。当然此时系统已经上线,用户嗷嗷待哺,你需要有替代方案过度,需要争取时间调整。
另一则小故事:
一个建筑队,全国各地到处跑,住的是一个茅草屋。遮风避雨是没有问题的,只是每到一地都要重盖,一到下大雨还到处漏水。修修补补的办法总有的,但总是很狼狈。有一天,有人告诉工程队,可以用可组合的铁框为骨架,彩钢为夹层,这样既可以连续拆装,节省成本,房子也结实牢固。
工人们开始担心了:“怎么组装啊,看上去好麻烦!”。工程队的老人也替工头担心,“那得花多少钱啊”,“会不会住不习惯”,工头出去考察了一番,回来一狠心,整了一套,虽然过程有些费劲,结果收益还是杠杠的。后来大家几乎都忘了曾经住过茅草屋。
当然,这里讲的不再是重构了,这种推倒重来的做法,我们叫它再工程(re-engineering)。与重构相比,他的风险更大,成本更高。但所谓高风险,高回报,如果它能带来更大的收益,甚至颠覆性创新,我们也值得去做。
再工程不是本文讨论的重点,打住!
对于最具挑战性的遗留代码重构,请移步到《浅谈遗留代码的重构》
[refactor]:https://book.douban.com/subject/4262627