代码简洁性的定义
多年前,我写了一篇博客文章解释计算机存在的问题,本质上说问题在于复杂性。几年后,我出版了《代码简洁性》,这基本上是一篇论文,描述了简洁性如何以及为什么是软件最重要的质量。
又过了许多年,我坐在一个房间里,与世界上一些最有经验的软件工程师一起,制定我们想要构建软件开发的原则和指南。在询问了房间里的每个人后,我得出了一个可怕的结论:没有人曾经定义过软件的"简洁性"是什么。
我以为——也许很天真——这是一个已知的事实,当我说"简洁性"时,每个人都知道我的意思。在某种程度上,这确实是真的。当你说"简洁性"这个词时,人们至少会有一些概念。但我注意到人们会以许多不同的方式应用它,其中一些完全不是我的本意。我会看到人们指向一个函数或文件说:“看,它现在代码行数更少,因此更简单!“或者说:“看,这个系统使用了某某设计模式,因此现在更简单了!“或者更糟的是:“这个系统现在完全通用,遵循了’大家都知道’你应该对软件做的所有事情,所以这很简单,对吧?”
于是,我开始寻找某种有效的简洁性定义。最终,我不得不自己提出一个。实际上我在几年前就想出来了,我一直想写一篇博客文章来介绍它,但一直没有做。那么这个伟大谜题的答案是什么?对于软件来说,什么是简洁性?
对于软件,“简单"意味着易于阅读、理解和正确修改。
关于这个定义有几个重要的事情。
首先,简洁性根本上是一个人为因素。它不是由机器引起的,也不是为机器而做的。只有人类阅读和理解软件。至于"正确修改”,是的,这可以由计算机完成,简洁性的某些方面可能涉及使自动重构工具等更容易修改事物。但重要的部分是我们希望人们能够正确修改软件。
这立刻告诉你,你永远不会编写一个计算机程序,能够神奇地完成所有软件的简化。工具绝对有助于人们简化和使代码易于理解。但它们不能完成所有工作。当有人想要在他们公司承担简化软件的任务时,如果他们的唯一解决方案是工具解决方案,要非常怀疑。如果他们说:“我们想通过改进工具来鼓励这种更好的实践,“很好!这是一个人为因素。实践涉及人。但永远不要忽视这样一个事实:简化软件总是涉及人类采取因果行动来发展这种简洁性(通常通过删除或修改难以理解的内容为更容易理解的内容)。
这也告诉我们,永远不会有自动分析系统告诉我们软件是否复杂。这是致力于软件简洁性的人们经常提出的问题——我如何衡量某物的简单程度?简洁性是一种只有人类才能体验的质量。除了观察者的观点外,它没有内在的真理。代码没有称为"简洁性"的内在质量。你不能在纸上写下一个数字来说明你的代码有多简单。你可以做的是从人们那里了解他们发现一段代码有多简单或复杂。(顺便说一句,你通常不能直接问他们有多复杂,但你可以询问他们的情感反应,这通常是复杂程度的最佳指标。如果他们发现某些代码或系统令人沮丧、害怕、愤怒、绝望等,这通常是复杂性的好迹象。)因此,任何软件简洁性的测量必须包括通过从人们那里了解情况进行的测量。一旦你通过人们完成了测量,你可能会发现某些模式或系统几乎普遍是坏的或复杂的,你可以编写禁止或修复这些模式的工具。但对复杂性及其有效性的理解来自于理解人们用代码做什么,他们对它的看法,他们的感受等等。
这告诉我们的一件事是,当一个人花一些时间关注代码的简洁性时,简洁性往往会出现。这听起来很明显,但如果你观察许多软件团队的行为,你会发现他们并没有基于这一事实运作。具体来说,这意味着某个人负责一段代码(不是"为此受责备"意义上的负责,而是"拥有它并积极处理它"意义上的负责)对于发展简洁性几乎是必要的。这在实际中表现出来。你可以看到,阅读、理解和修改未维护、无人拥有的代码几乎总是随着时间的推移变得越来越困难。我只说"几乎总是"是因为我没有看过世界上每一段代码,并且为了使这完全正确,你必须无限期地观察它(也就是说,它未维护的时间越长,往往变得越来越复杂,所以有时它必须未维护很长时间你才会真正遇到这种情况)。但在我见过的每一种情况下都是如此——我不知道有任何反例,一段代码在未维护的时间越长时变得更简单。当你让软件无人拥有时,你就是在允许它随着时间的推移变得越来越难以阅读、理解和维护。
除了缺乏所有权之外,复杂性的另一个主要原因是时间压缩。事实上,这是复杂性的最常见原因——可能是复杂性的唯一真正原因。通过"时间压缩”,我基本上是指让人们感觉他们没有足够的时间。有趣的是,这最常由程序员自己对自己做。他们说这是由他们的管理层做的(“他们给了我这些截止日期,现在我必须偷工减料”),有时这是真的。但更多时候,开发人员自己只是感到一种压力要"完成"这项工作。他们觉得他们需要完成某事,否则有人会生气,或者他们会有麻烦,或者他们不够快,或者有人会认为他们是坏程序员,或者,或者,或者……但通常这些都不是真的,实际情况是他们完全有自由多花一点时间以正确的方式做某事。
如果你认为这不正确,下次你看到一个临时解决方案时,问一个开发人员他们为什么这样做。他们会告诉你他们不理解他们在做什么(复杂性的另一个主要原因),或者他们会告诉你类似:“嗯,那个其他库很难使用并且工作不正常,所以我不得不这样做。“但仔细想想。开发人员通常是在说:“我不想花时间修复那个其他库。“哇,你说,这很苛刻!修复那个其他库可能有很多工作!没错,但他们真的有时间做吗?也许他们有。也可以说:“我觉得对那个库不负责任,“这再次看到责任在复杂性原因中的作用。也许它"超出了他们的控制”,比如它在另一家公司或类似情况。好吧,这仍然是他们愿意承担的责任水平的声明。我不是说那里的决定是坏的,只是你必须认识到你正在有意识地决定承担多少责任(你可以联系另一家公司,向他们报告,与他们合作修复它等),并且你故意决定制造复杂性,而不是花时间发展简洁性。
无论如何,我希望这让你更好地理解简洁性是什么以及实际上导致它的原因。记住,当你与某人谈论简洁性时,首先确保他们知道你真正谈论的是使代码更易于阅读、理解和正确维护!
-Max
评论
Steven Gordon, PhD 说: 2020年5月20日上午4:47 软件开发主要是一个人的问题,而不是技术问题(不确定谁首先说的),所以简洁性不是技术事物是完全合理的。但是,这带来了人类问题的所有混乱。对一个人"易于阅读、理解和正确修改"的代码可能对另一个人不容易(反之亦然)。这使得鼓励或允许单个人"拥有"代码库的任何部分都存在问题,因为那个人的简单想法可能非常特殊。鼓励共享所有权、频繁配对甚至群体编程实践的最佳原因之一是促进产生许多人都同意是简单的代码,而不仅仅是"所有者"认为简单的代码。
顺便说一句,我用于代码简洁性的一个"技术"标准是它与所需注释量成反比。
回复
Max Kanat-Alexander 说: 2020年6月3日上午8:32 嘿Steven!完全同意这对每个人都是不同的。我也同意你可以在什么是简单上达成一些一致,配对编程和代码审查都有助于这一点!这实际上有点像写作,理解读者的观点是有帮助的。
就像物理宇宙中的每一个问题一样,对此没有"完美"的解决方案,但有_好的_解决方案。在实际实践中,绝对可能为目标读者在上下文中使事情变得简单。
-Max
Steven Gordon, PhD 说: 2020年6月3日下午2:11 有很多问题有完美的解决方案,只是没有涉及人类的问题。
我文章的主要观点是反驳"某个人负责一段代码(不是’为此受责备’意义上的负责,而是’拥有它并积极处理它’意义上的负责)对于发展简洁性几乎是必要的”。在40多年的经验中,我发现代码库部分的个人所有权几乎总是导致特殊的复杂性。老派的解决方案是代码审查,但那发生得太晚且太不频繁。通过配对和群体编程的共享代码所有权在实现可维护性和简洁性方面已被证明比个人所有权更有效。
回复
Kurt Guntheroth 说: 2020年5月20日上午7:51 即使提出的简洁性定义也不充分。而不是"容易”,尝试"尽可能容易”。这解释了一个操作系统内核模块永远不能像具有相同行数的CRUD屏幕那样简单,因为内核模块在更多约束下工作。
即使这种简洁性的描述也未能成为定义,因为你甚至原则上不能使用它来判断一段软件是否简单。我认为,如果我们原则上不能构建一台机器来确定一段软件是否简单,那一定是因为我们实际上不理解简单意味着什么。也许我们可以解决"更简单"这个较小的问题。我们至少应该能够判断一段软件是否比另一段产生相同输出的软件更简单。
回复
Steven Gordon, PhD 说: 2020年5月20日上午11:19 Kurt,
一个描述不必可测量才能有资格作为定义。有一个可测量的定义会很好,但除非你有一个好的候选者,否则指责一个定义不可测量是不公平的。
Max Kanat-Alexander 说: 2020年6月3日上午8:34 嘿Kurt。确实,不同的事物以不同的方式简单。这没关系。物理宇宙中任何地方都没有绝对。这只是另一个案例(就像所有情况,对于所有事物),你必须以灰度思考,而不是黑白。
-Max
Nelson Ferragut 说: 2020年5月20日上午8:34 优秀的概念分解——谢谢!如果我要给"易于阅读、理解和正确修改"附加一个词,我会使用"可维护性”。你会说"简洁性"和"可维护性"有区别吗?
回复
Max Kanat-Alexander 说: 2020年6月3日上午8:35 嘿Nelson!我想我通过说"正确修改"以更实际的方式捕捉了可维护性,因为这捕捉了人们试图用维护做什么——进行与他们打算做的更改匹配的更改。
-Max
Nelson Ferragut 说: 2020年6月3日下午12:11 嗨Max,这有道理。可维护性在其核心包含的内容比简洁性少。我可以接受这一点。再次感谢。
回复
Jay Kishan 说: 2020年10月27日上午2:53 你好max。非常好的博客你提交了,以及你如何解释代码使其简单和容易。所以,感谢分享这篇博客。它对我帮助很大。
回复
Ashik Rahman 说: 2021年1月9日下午9:16 我为我的论文读了这篇文章。真的这篇文章对我帮助很大。感谢作者写了这么好的文章。
回复
adamwilson1234 说: 2022年6月5日上午9:38 “当每个人都负责时,没有人真正负责。” ― Albert Bandura, Selective Activation and Disengagement of Moral Control
我见过团队负责系统的不同部分,但有时只在代码审查阶段。其他团队会修改代码,然后获得所有者批准。如果你必须这样做,更大的组织至少应该促进团队间关系建设、信任建设,并灌输对一套核心"简洁性"原则的认同。这只是良好的入职实践。不要留给个人去主动联系他人。
回复
adamwilson1234 说: 2022年6月5日上午9:40 顺便说一句,我喜欢这篇文章
回复
BugRaptors 说: 2024年1月22日上午4:34 你好Max,你的博客很棒!你简化和解释代码的方式真的很有帮助。感谢分享这个宝贵的资源;它对我非常有益。
回复
Software Tester 说: 2024年12月24日上午10:39 感谢分享这篇博客,Max!刚刚下载了你的免费电子书。
回复
The Psychology of Patrick Star: Is He Really Dumb or Just Carefree? - The Cartoon Journal 说: 2025年3月20日上午9:51 […] Patrick Star是一个体现人性复杂性的角色——愚蠢和深刻简洁性的混合体。他对生活的无忧无虑的态度提供了一个清新的视角,鼓励我们重新评估我们的[…]
回复