软件行业创造了各种术语、设计模式和设计原则,其中大部分是为了更好的应对变化,这一点和敏捷开发的目标是一致的。在《The Pragmatic Programmer》(程序员修炼之道》第二版中,作者提出好的设计就是“更易于修改的设计”(Easier To Change,ETC)。
为什么解耦是好的?因为隔离会让修改变得容易——ETC。
为什么单一职责原则很有用呢?因为所有的修改只发生在一个地方——ETC。
为什么好的命名很重要?因为好的名字会让代码易读,而进行修改前要读懂它们——ETC!
很多人写完代码后,就不想再改了,似乎是终于做完一个苦差事,或者已经竣工了,还改啥呢。但实际上,代码一直在那里,就需要一直被维护。因为:
- 需求变化了。这也是软件正常变化的一个因素
- 自己对业务和技术有了更好的了解。这时候需要重构代码以符合自己的新的认知,防止代码腐烂
- 发现 bug。这个没啥说的,肯定要改
可能我们很多人职业生涯的大部分时间都在和坏架构和烂代码做斗争,似乎认为不随意修改代码是理所当然的,但其实我们可以改变这个局面,从自己写的每一行代码开始。
为什么大部分软件没有变得更好?
我们知道了好的软件就是要易于修改,那为什么大部分软件没有做到这点呢?
让我们用五个 Why 来看看能不能找到具体的原因:
- 为什么大部分软件没有变得更好?因为代码逐渐腐烂,基于腐烂的代码很难写出好的代码
- 为什么代码会腐烂?因为最开始的代码写的不好
- 为什么最开始写的代码不好?因为赶进度或者对业务和技术的了解不够深入,导致最开始写出的代码比较“烂”
- 为什么后来不进行重构,让代码变得整洁和易于修改?因为代码耦合比较严重,改了肯定会出问题
我们只用了 4 个 Why 就梳理出了一个常见的逻辑:
- 很多软件最开始的代码都不是最好的,仅仅能工作就好
- 要让代码整洁和易于维护,就要持续的重构
- 很多开发者不敢重构,是因为害怕改错了,带来更多的问题
很多开发者甚至会想:我自己写的代码,我后面都不想碰了。这其实是对自己专业能力的一个否定,如果我们的代码腐烂到让我们自己难以维护时,那我们会做的事情通常是什么?离开。把烂摊子留给别人,然后开始新的一轮自我否定的循环。
专业的程序员怎么能容忍自己的代码持续恶化和腐烂呢?
解决这个问题最好的方式是测试驱动开发(TDD)。
TDD 三规则:在我们开发新功能时
TDD 可以描述为下面三个简单的规则:
- 先编写一个因为缺少代码而失败的测试,然后才能开始写生产代码
- 只允许编写一个刚好失败的测试——编译失败也算
- 只允许编写刚好能使当前失败测试通过的生产代码
很多程序员会觉得这样很荒谬,因为他们习惯于一次性写完所有的代码,然后根据运行结果“补”测试。这还是好的情况,有些人承诺的“补”测试后来从来就没有实现过。
另外程序员还会觉得这样会破坏自己的思路,因为使用 TDD 可能意味着每过几秒就会切换一次测试和代码,程序员很多时候不能一次性完整地写完一个函数,甚至连一个 if 语句和 while 循环都不能一次写完。
TDD 已有定论,TDD 确实可行,每个程序员都应该适应和掌握 TDD。
TDD 三规则带来的好处远远大于“坏处”,首先可以保证任何的代码在一分钟前都是可以工作的。
另外,它会让我们的调试变得很容易,我只需要调试最近一分钟的代码就行了。
最后,它可以极大的降低 bug 的发生率和严重性,因为我们的代码都通过了测试,bug 自然变少了。从 IBM 到微软,从Sabre 到 Symantec等各种不同的团队和公司,经历了 bug 变为1/2 甚至 1/10 的过程。
测试也是程序员的完美文档。文档会过期,而测试不会。通过查看测试,你就能知道代码是如何使用的了。
遵循三规则,整个过程会变得很有趣。每个新的测试都是一个挑战,每次通过一个测试就赢得了一次小的成功。你的工作就变成了一连串的小挑战和小成功。这个过程不再无聊,让人有达成目标的成就感。
TDD 三规则:在我们重构时
当我们重构时,TDD 可以消除我们的恐惧,给我们以勇气,我们再也不是那个害怕自己的代码在不知道什么时候会捅出乱子的“孩童程序员”了,我们是专业人士。专业人士看到糟糕的代码,怎么能不去重构呢?
想想每次重构后,你的测试代码在 60 秒之内就能告诉你重构是否破坏了什么东西,你是不是感觉很放心呢?
使用 TDD 三规则结合重构的过程,就是广为人知的红 - 绿 - 重构循环:
- 创建一个失败的测试
- 使测试通过
- 清理代码
- 返回1
重构是一个持续的过程,我们在一两分钟内制造了混乱,然后立即清理这团小混乱。
重构不应该出现在时间表和项目的计划中。不应该给重构预留时间。重构是我们每分钟、每小时软件开发活动中不可分割的一部分。
就算是大型系统,也不要预留重构时间。相反,一点点的重构,按照正常的敏捷周期添加新功能。
不使用 TDD = 不专业
最后,引用 Bob 大叔的观点:TDD 是专业人士的选择。它是一项能够提升代码确定性、给程序员鼓励、降低代码缺陷率、优化文档和设计的原则。对 TDD 的各项尝试表明,不使用 TDD 就说明你可能还不够专业。
你们团队在使用 TDD 吗?如果没有,下一步你打算如何引入这项实践?
参考:
- 《The Pragmatic Programmer》(程序员修炼之道》第二版
- 《Clean Agile》(敏捷整洁之道)
- 《The Clean Coder》(代码整洁之道——程序员的职业素养)
网友评论