代码整洁之道,是胡说八道还是常识?
共同的故事
鲍勃开始在一家新公司工作。很快他就意识到,他的新工作将与一个非常老旧且复杂的遗留系统息息相关。这套系统代码贫乏,缺乏测试,也没有任何文档。对于底层工作流程,没有任何解释。这些工作流程本应体现为解决业务需求而做出的决策,但这些业务需求最终是由某个利益相关者提出的,然后被添加到待办事项列表中,最终被实现并交付。然而,那位利益相关者以及最初的开发人员都已经离开了公司。
所谓领域本身,总是与基础设施紧密相关……许多类的代码超过一千行……方法中包含大量的 if 语句,导致执行路径繁多……命名空间深达十层……大量使用类扩展……
几乎每一项任务都是修复 bug。有些 bug 是很久以前产生的,有些则是最近通过新的修复引入的。尝试调查代码历史以找出某些更改的原因以及它们与其他代码部分的关联也无济于事,因为提交记录组织混乱,而且信息含糊不清……
为了修改一个很小的行为,他不得不花费数小时调试代码,试图理解代码的含义。有时,一整天的工作下来,最终的结果也只是修改或添加了大约 10 行代码。大部分新增代码只是增加了一个 if 语句,用于判断某个值是否错误,从而触发 bug……类本身没有进行验证……到处都是 getter 和 setter 方法……
他遇到了代码错误……
为什么这种情况如此频繁发生?
首先,我们得澄清一点:请不要误会我的意思!我并不是想简单地说代码一团糟,然后把责任推给开发者或公司,因为那样做于事无补。没错,我们确实有很多不专业的开发者,但一味指责并非问题的关键,我们需要从更广泛的角度来深入分析。
那么,为什么会发生这种情况?为什么我们总是深陷其中?
造成这种情况的原因有很多。想象一下,一家公司正在发展壮大,为了更快发展而不断招聘员工,新开发人员加入,老开发人员离开,动态的业务需求不断变化,IT部门和业务部门之间的沟通存在障碍,开发人员专注于完成冲刺目标,这种紧迫感始终给项目上的每个人带来压力,没有人关心用户与产品之间的关系,没有人关心编写测试,开发人员无法进行设计,因为设计似乎无法带来短期价值,TDD(测试驱动开发)只是一种理念,公司不愿投入时间培训团队,最有价值的实践是解决眼前问题的方法,英雄文化盛行,我们总是需要更多的日志来试图了解发生了什么,我们需要引领市场……
我可以将其概括为仓促行事且缺乏研究的结果。
在这种情况下,输出的错误代码至少是全面的。我们的世界有时并不美好,我们必须面对这个现实。
那意义何在呢?
我带你来这里不是为了给你一个简单的解决方案,因为根本不存在这样的解决方案。
我写这篇文章的目的是为了回应那些对开发者抱怨代码糟糕时总是千篇一律的回答:听着……系统能运行,能为公司赚钱。这才是最重要的,开发者拿工资就是为了维护它。
好吧……我明白了,我也同意“最有价值的东西是运行中的软件”。这听起来很神奇,也能安慰我们这些开发者。然而,我们仍然面临着一个很大的问题。
它真的是一款有价值的运行软件吗?
一家高度依赖技术运营并渴望创新的公司,如果软件沦为维护难题而非推动业务发展的工具,就永远无法实现其目标。回到鲍勃的案例,几乎不可能对应用程序进行任何新增或更改。如何在不破坏其他功能的前提下,交付一项能够改变业务流程的新功能?风险太高,未知的副作用可能是灾难性的。这样一来,公司与其说是追求创新,不如说是在勉强生存……如今只剩下蛮力……而竞争对手正在崛起。
在我看来,在这种情况下很难看出它能产生什么价值。
软件现在能赚钱并不意味着软件将来也能赚钱。
糟糕的代码会摧毁成熟的公司,也会让初创公司过早夭折……并不是因为开发人员不是一线人员,我们就不能成为问题的原因。
编写整洁的代码,也就是用心编写代码,也就是先测试,才是打造真正能够伴随企业共同成长的软件的关键。让我们一起学习,精进技艺,学习如何应对紧迫的开发任务!
作为开发者,我们有责任编写简洁的代码……这并非是为了更快地实现明天的目标,而是为了更快、更安全地实现明年的目标……
你有没有想过你的经理对你的期望是什么?你觉得是短期业绩还是长期业绩?
我知道,我知道……完美是不可能达到的……有时候我们确实需要处理紧急问题。但是,我的意思是,我们不应该随波逐流,接受糟糕的代码……
我的经验说明了什么?
我确实有一个真实的案例,我们在初期投入了大量时间来实现开发环境和生产环境的完美对等,为每个项目运行实例创建完全隔离的数据库,为整个应用程序编写端到端测试,为每个代码库编写功能测试和单元测试,实现自动化部署,采用六边形架构……嗯……这些对很多人来说都是遥不可及的哲学概念……在他们看来,简直就是胡扯……
这并不容易……充满挑战。然而,我们的努力最终打造出了一个几乎没有缺陷的产品。每当发现新的缺陷,我们都会编写新的测试用例。部署快速、安全,并且可以随时执行。添加新功能很容易,修改旧功能也很容易……这就是测试驱动开发 (TDD) 的优势……这就是敏捷团队的精髓!
我们应该抵制糟糕的代码,并始终做到最好。唯一的错误就是不去尝试……
以下是一些参考资料:
- Robert C Martin,2008。《代码整洁之道:敏捷软件开发手册》
- Nat Pryce;Steve Freeman,2009。《以测试为指导的面向对象软件开发》

