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