Engineering

[Engineering] 编程哲学(八):偿还不起的技术债务

2017-05-11  本文已影响38人  何幻

修改代码的风险

重构,就是在不改变外部行为的前提下,有条不紊地改善代码。
为了保障软件的外部行为,唯一的办法就是通过测试。
因此,重构是建立在完备的测试覆盖基础之上的。

如果我们不能保证修改后的代码还能提供相同的功能,
那么这种修改就是错误的,会给用户带来极大的损失。
在有风险意识的团队中,不会同意发生这样的修改

什么是所有的功能

一个涉及几百个页面的网站,多个角色处于不同状态的用户都可以访问它,
那么它总共提供了哪些功能?
页面之间的跳转,以及同一个网页为他们展示的不同功能,都是业务逻辑的细节表现。
没有人知道“所有的功能”指的是什么,因为太复杂。

代码中的某个分支,看起来似乎用不到,但是可能就是有那百分之一的用户会使用它。
另外某处,为什么这里要向一个莫名的服务器发送请求,很可能必不可少。
某个类到底有没有人在使用它,我们只知道自己的依赖,很难知道谁依赖了我们。
如果不确定谁在以什么方式使用它,就不能进行修改。

偿还周期

哪怕我们已经有了完备的测试,如果重构所花费的时间周期太长,还是很危险,
我们不得不在这段时间内,同时应付重构工作和新功能的开发。

框架迁移就是这样的一个典型例子,如果我们打算把旧框架的功能迁移到新框架,
那么几乎所有的功能,都不得不在新框架下重新开发并测试一遍,
新需求也不得不在旧框架中完成,并且最终还得再迁移过去。

高利贷

我们很容易低估重构的成本,
假设框架迁移需要n个“人日”的工作量,团队中有x人,需要y天才能把事情做完,
则n不等于xy。

因为这y天中会有新功能要开发,这些新功能需要xy人日的工作量,
于是,人们必须加班,假设人们比原来努力t倍,
则,n+xy=txy,因此xy=n/(t-1)

如果以前已经在加班了,那么我只能说,真是太不幸了。

如果框架迁移需要100人日,有5个人来完成它,他们都用1.5倍的努力进行工作,
则事实上需要40天才能完成,而不是20天,居然比原来估算的时间多了一倍。
这40天中,每人每天必须想办法比原来多做一半的事情,
我们知道,就算加班其实也很难达到这个目标。

这就是技术负债的利滚利效应,也是著名的牛顿问题
偿还周期越长,所需偿还的债务总量就越多。

试错的代价

重构其实很难进行下去,即使进行下去了也做的很不彻底,
项目中混杂了各个时代的代码遗骸,战场从来没有干净过。

一开始就寄希望于用重构来逐渐解决问题,可能是有害的,
代码中会留下很多做到一半的事情,开发者必须小心谨慎的理解所有技术细节。

快速试错能反映出这种侥幸心理,虽然快速试错的目的是为了降低最终出错的代价,
但是实际上很难承认自己的确是错了,人们会想尽办法弥补它,
于是,等我们看到失败时,再退出已经来不及了。
快速试错通常是一个借口,掩饰自己还没有想清楚它。


参考

重构:改善既有代码的设计
测试驱动开发
程序员的职业素养
人月神话

上一篇 下一篇

猜你喜欢

热点阅读