在当今快速发展的软件行业中,不断涌现的新理念、技术和工具对开发者的工作方式产生了深远的影响。那么,敏捷开发在现代软件开发中还适用吗?测试驱动开发(TDD)是事倍功半还是物有所值?实践代码整洁之道对企业有哪些好处?
针对这些问题,近期 InfoQ 有幸专访了著名软件工程师、作家和讲师“Uncle Bob”——Robert C. Martin,与读者朋友们共同探讨。
Uncle Bob 是敏捷开发宣言 17 个奠基人之一,在软件开发社区中享有极高的声誉。并出版了多本关于软件开发的书籍,其中包括《Clean Code》、《The Clean Coder》等。目前,他的新书《Functional Design》也已在中国上市。《Clean Architecture》一书,经过国内4位知名的架构师精心翻译,将于金秋10月由机械工业出版社出版,欢迎关注。
部分精彩观点如下:
软件最好在短周期内生产,同时拥有大量的反馈和团队互动。
越想快速前进,代码就必须越整洁。
并不是软件科学退化了,而是这个领域因大量尚未学习明白它的年轻学生涌入而被淹没。
人工智能不是人类智能的替代品。
使用 AI 来编写测试的程序员会发现 AI 只是重复了他们的错误。
业界真正需要的是一个完善的学徒制度。
软件行业最大的变化其实是硬件领域缺乏变革。
人工智能发展的瓶颈已经隐约可见。
以下内容基于书面采访整理,经过不改变原意的编辑。
InfoQ:非常高兴看到您的新书《Functional Design》在中国上市,中国的程序员们都非常关注这本书。我们了解到,过去近 30 年您参与撰写并出版的编程类书籍已经超过十本。最初您是因为什么样的契机开始写书的?是什么推动着您持续产出这么多书籍? Uncle Bob: 说实话,我真不知道自己为什么会成为一名作家。我几乎从记事起就开始写作了。小时候,我每天都会写东西。我写过许多故事,也写过很多非虚构作品。当我成为一名程序员后,继续写作对我来说是很自然的事情。怎么说呢?我就是喜欢写作!
InfoQ:您是如何开始您的软件开发生涯的?在早期的职业生涯中,有哪些关键的经历或项目对您影响最大?您的昵称 uncle bob 有何含义吗?Uncle Bob: 我的第一个程序是为一台小型塑料计算机编写的,那是我十二岁生日时母亲送给我的礼物。那台计算机叫做 Digi-Comp I。它有三个塑料滑块,代表三个比特位。它有弹簧加载的金属杆,起到与门的作用。简而言之,它是一个由 6 个三输入与门驱动的三位有限状态机。通过将小塑料管插入三个滑块上的插脚来编程,管子会阻挡与门的金属杆。这台机器可以被编程来从零数到七,或者从七倒数到零。你可以编程让它进行二进制加法,将两个比特相加并产生和位和进位。还有许多其他的小程序可以让这台机器执行。最终,我被深深吸引。我知道了我想要用我的余生做什么——我想要让那样的机器工作。
多年来,我参与了许多项目。我从事过金融、工厂自动化、嵌入式实时系统、计算几何、电话、电信、高能物理等领域的工作。可能最具影响力的是那些使用 8080 微处理器控制电子设备以测量电话线路质量的电话项目。
“Uncle Bob”这个名字是在 80 年代末由一位同事给我起的,很快就被大家记住了,我也认为这个名字很不错。
InfoQ:您提出了多项影响深远的软件设计理念,比如敏捷开发、代码整洁之道等,您能谈谈是哪些经历或人物帮助您塑造了您的编程哲学吗? Uncle Bob: 在我的生活和职业生涯中,有很多人对我产生了影响:Grady Booch、Martin Fowler、Kent Beck、Jim Newkirk、Tim Ottinger、Michael Feathers、Jim Coplien……我可以继续列举下去,值得提及的人实在太多了。
至于塑造我哲学观的经历,我参与过许多不同类型的软件项目。在每一个项目中,我都注意到了软件设计与架构方面的相似问题。多年来,这些问题逐渐凝聚成了一些通用原则。
InfoQ:作为敏捷宣言的创始人和签署者之一,您认为敏捷开发对软件开发行业最大的贡献是什么? Uncle Bob: 敏捷软件开发的最大贡献,简单来说,就是重新唤醒了一个理念:软件最好在短周期内生产,同时拥有大量的反馈和团队互动。这个理念在 50 年代就已经被知晓和实践,但在 70 年代初,一种极端的前期规划理念取代了它。这种替代是由于程序员群体的人口结构变化:随着大量拥有计算机科学学位的大学毕业生涌入,程序员的平均年龄下降了近 20 岁。
Uncle Bob: 敏捷,像所有软件理念一样,可能会成为营销炒作和稀释的牺牲品。敏捷开发是由程序员为程序员创建的,但早期它就被一群寻求 Scrum Master 认证的项目管理者侵入,然后被曲解。这群人教授和实践了他们所谓的“敏捷”,但这与原始的敏捷原则并不一致。我对 Capital One 的案例不熟悉。但对我来说,一些公司会放弃被曲解的 Scrum 和敏捷版本并不奇怪。
敏捷的正确方法是遵循敏捷宣言中的四项声明。Kent Beck 的《极限编程解释》一书中很好地描述了一套最佳的敏捷纪律。
InfoQ:您提出的 SOLID 原则对面向对象设计有着深远的影响。您能解释一下这些原则背后的基本思想吗? Uncle Bob: 所有的 SOLID 原则都是管理依赖关系的技术。总体目标是将软件系统划分为一组组件,这些组件的相互依赖关系被组织得如此之好,以至于变化不会从一个组件传播到另一个组件。
InfoQ:有人认为在微服务等技术盛行之后,SOLID 原则并不完全适用了(https://www.infoq.com/news/2021/11/solid-modern-microservices/)。那么您认为现代软件设计是否需要有一套新的原则? Uncle Bob: 在我职业生涯的几十年里,给我留下深刻印象的一件事是,软件设计与架构的原则是不变的。我们并不需要一套新的原则来处理“现代”软件实践——因为“现代”软件实践与不“现代”的软件实践并没有那么大的不同。
微服务就是一个很好的例子。几十年来,软件开发人员一直在将组件隔离成可以独立执行的服务。微服务的概念一点也不新。而且,它也不是许多系统的特别合适的方法。对于那些适合使用微服务的系统来说,SOLID 原则为服务的设计以及整个系统提供了一个很好的指导。
InfoQ:您从 1970 年开始从事软件行业,那时候甚至还没有 C 语言,而现在主流的 Java、Python 语言出现得更晚,Rust、Go 等语言甚至是在您的“Clean Code”出版之后。对于 C 可能非常易于使用“Clean Code”的一些原则,但是否也适用于 Java、Rust、Swift、Python 等这些后期出现的静态、动态语言? Uncle Bob:Clean Code 的原则适用于所有编程语言。你可以在 Rust 中实践它们,在 COBOL 中,在 Swift 中,在 FORTRAN 中,在 Clojure 中,在 Assembler 中。它们适用于静态语言如 Kotlin,动态语言如 Ruby,堆栈语言如 Forth,以及逻辑语言如 Prolog。
InfoQ:如今的企业希望做到快速推出产品并快速试错,那么相对以前,现在的开发者们应该如何构建干净的代码,哪些原则是必须坚守的,哪些是可以妥协的?干净代码能给企业以及想盈利的产品带来哪些好处? Uncle Bob:“早失败,常失败”是敏捷原则之一,它与 Clean Code 完全兼容。实践代码整洁之道并不慢——它很快,代码整洁比代码混乱时更快。你越想快速前进,你的代码就必须越整洁。
InfoQ:对于一些在 IT 行业从事了 20 年或以上的人来说,其实都在目睹“软件科学”的不断退化。二十年前,我们写软件会用到“设计模式”、会用 UML 做设计、做完美的需求分析和画流程图。如今,我们看到许多年轻开发者不再热衷于学习和应用设计模式、UML 等。您认为造成这种现象的原因是什么?如何平衡过度设计和功能需求? Uncle Bob: 世界上程序员的数量大约每五年翻一番。自 60 年代以来一直如此,而且在未来几十年内很可能仍然如此。这意味着世界上有一半的程序员经验不足五年。这就解释了问题中的所有情况。并不是软件科学在退化,而是这个领域因大量尚未学习明白它的年轻学生涌入而被淹没。 这对设计模式、敏捷、SOLID、UML 等都是如此。
解决这个问题的方法是提升教学质量。我们这些有 10 年、15 年和 20 年经验的人必须承担起责任,教育涌入我们领域并稀释我们职业的大量年轻程序员。
InfoQ:您提到过您理想情况下的 TDD 是每行代码编写一行免费的测试代码,并达到 100% 的覆盖率。但实际有一些软件,特别是互联网企业,并不重视测试,比如说 Tiktok 作为一款全球现象级的应用,似乎并没有严格遵循 TDD 的原则,他们用 QA 代替了单元测试,但实际上 Tiktok 运行还比较稳定。您如何看待这样的一些实践?您认为在现实的软件开发中,尤其是互联网企业,这种状态是否可行并可持续?为什么? Uncle Bob: 我很推荐 TDD。有些人不遵循这一建议,那是他们的选择。然而我猜想,一个不太重视测试的软件团队,必然花很多时间在调试上,并且会因为调试而显著减慢速度。我个人更喜欢通过避免调试来快速推进。
我还认为,一个不太重视测试的软件团队,也不会太重视重构。没有一套测试,重构是非常危险的,系统必然会因为开发者害怕通过重构来保持代码整洁而退化。最终,随着时间的推移,这些团队将不得不处理越来越混乱的系统,他们的速度会因此减慢。
InfoQ:作为测试驱动开发的坚定支持者,您如何回应那些认为 TDD 会降低开发速度的观点?对于那些不重视测试,甚至认为测试是浪费时间的年轻企业,您有哪些建议?如何说服他们认识到 TDD 的重要性? Uncle Bob:TDD 提高开发速度,因为它减少了调试,并使得重构成为可能。重构允许系统的设计与代码持续被清理和改进,这使得团队中的每个人都能更快地工作。做快的唯一方式是做好。
InfoQ:如今,生成式 AI 越来越强大,围绕各类编程类 Copilot 有很多讨论。与我们之前倡导的“提升专业化水平”方向不同的是,这些工具厂商都在鼓动不懂或不精通编程的非专业人士进入软件行业,并编写自己的软件,您认为这会对 IT 行业造成哪些影响? Uncle Bob: 灾难。人工智能不是人类智能的替代品。人工智能可以是很好的工具,但只有在知道如何使用这些工具的人手中才是如此。
InfoQ:许多开发人员已开始将 ChatGPT 和 Copilot 等工具集成到他们的日常工作流程中。那么,在生成式 AI 时代,TDD 是否比以前更为重要?我们注意到已经有一些利用大模型生成测试的案例,您如何看待“使用 AI 为代码生成测试”?您有没有利用 AI 进行测试的建议方法? Uncle Bob:TDD 相当于会计实践中的复式记账。会计人员将每一笔交易输入两次,一次作为资产,第二次作为负债。这两笔交易遵循不同的数学路径,直到它们在资产负债表上相互抵消至零。遵循 TDD 的程序员将每一段代码编写两次,一次作为测试,第二次作为生产代码。它们遵循互补的执行路径,直到它们零和测试失败,在错误报告上相遇。
TDD 和复式记账的要点是让个人输入两次,以捕捉该个人犯的错误。我们不希望自动化系统,如人工智能,来编写我们的测试,因为那违背了让个人陈述和重申他们意图的目的。使用 AI 来编写测试的程序员会发现 AI 只是重复了他们的错误。
InfoQ:您现在仍在软件设计和工程实践领域深耕,没有停止对编程的研究,这五十年来,您是如何一直保持对编程的热爱的? Uncle Bob: 我在十二岁时就爱上了编程,并且从未回头。我想一直写代码直到我去世,而且我不想很快就去世。总有一天,他们会发现我,我的鼻子卡在笔记本电脑的键盘之间,屏幕上显示着一个失败的测试。
InfoQ:您经常提到软件工匠(Software Craftsman)和工匠精神。您能解释一下何为软件工匠精神,并分享一些如何培养这种精神的建议吗? Uncle Bob: 软件工匠精神就是你每天下班回家后,站在镜子前,对自己说:“我今天干得不错。” 很多程序员下班后却需要洗个澡,因为他们那天制造的混乱。软件工匠精神关乎对工作的自豪,知道自己的代码会被他人看到并赞赏,你是如何精心打造代码的,以及你对细节的关注。
InfoQ:您曾表示程序员要持续学习,比如在一门新的编程语言还没流行之前就提前感知到并去学习它。您最近还在学习什么新语言吗?在您的职业生涯中,想必使用过多种编程语言。您认为选择编程语言时应考虑哪些因素?程序员如何才能提前感知到未来可能变得重要的新语言的来临? Uncle Bob: 最近我又开始温习一些编程语言:写了一些 Python 和 Go 代码——这些语言我已经多年没碰了。也稍微研究了一下 Rust,尽管我现在还不能算是一个 Rust 程序员。几年前,我花了点时间学习 Elixir,而且我经常玩玩 Lua 。
学习新语言时,最重要的考虑因素是它是否能让你感到乐趣。当学习变得有趣时,你不仅会学得更快,而且学习本身就是目的。随着时间的积累,你会逐渐明白新语言对你的职业生涯是否有帮助。但在职业生涯的初期,这一点并不是特别重要。等到你能够在团队和组织的方向上发表意见时,实用性和实际效益的考量就会变得更加重要。
InfoQ:您认为当前的编程教育是否足够培养出优秀的软件开发者?有哪些改进的建议? Uncle Bob: 不,我觉得大多数编程教育都远远不够。业界真正需要的是一个完善的学徒制度。新程序员应该在资深程序员的亲自指导下,通过实践操作和严格监督来学习——就像医生和律师那样。
InfoQ:在您看来,软件开发领域过去十年最大的变化是什么?未来十年最值得期待的变化又是什么? Uncle Bob: 过去几十年,软件行业最大的变化其实是硬件领域缺乏变革。摩尔定律大约在 2005 年就走到了尽头,自那以后,计算机的速度并没有显著提升。存储技术在接下来的十年里持续进步,但现在这种进步也放缓了。我成长的时代,机器的性能以指数级的速度提升,变得更快速、更小巧、更经济、存储容量更大。每隔一两年,我们就得更新换代,因为旧设备无法胜任新软件的需求。每隔一两年,我们的视野就会因为新技术而拓宽,探索更多可能性。但今天的软件开发者面临的是一个技术发展的瓶颈期,机器的性能不会再像以前那样指数级增长了。虽然可能会有一些逐步的改进,但摩尔定律带来的迅猛发展已经结束。
人们很容易误以为人工智能是摩尔定律那样的技术革命,但实际上并非如此。人工智能需要巨大的资源投入,而这些资源是有限的,因此人工智能不可能无限制地指数级增长。一些技术改进,比如专用芯片,可能会带来一定的进步,但人工智能发展的瓶颈已经隐约可见。
在未来十年,我们应该更多地关注提升我们的专业技能,而不是单纯依赖技术的进步。 我们应该致力于成为更优秀、更专业的程序员。我们应该努力建立和完善软件行业的纪律、标准和道德规范。
Uncle Bob: 开发者都是我的同胞,我向世界各地的开发者致以崇高的敬意。对每一位开发者,我都要说一句:保持代码的整洁,认真做好每一份工作,无论是在编程还是在生活中都要细心谨慎。当你提交代码时,确保它比你检出时更加整洁。