编写良好的代码:如何减少代码的认知负荷

良好的代码意味着:低bug,性能好,修改容易。好的代码是有高影响力的,这也许就是坊间流传10倍效率的开发者的主要原因。

在这里讨论五个主要的编程概念。记住它们,编写好的代码应该是轻而易举的。

剔除个人怪癖
当你读了一些文章,它们吹嘘的新的技巧进入了你的头脑,然后你编写了所谓聪明的代码,你的所有同行将会印象深刻。

问题是,人们只是想修复bug,然后继续开发。你的这些聪明把戏通常只会造成分心。正“ 应用神经科学到软件开发 ”中所说的,当人们必须看懂消化你的代码段时,他们“心理压力”如果增加,就很难取得进展。

不要以需要解释的方式太过于个性化你的工作。不要以“你的方式”编写代码。只需遵循编码标准,通过人们期望的方式进行编码,使您的代码可预测并且易于阅读。

划分和征服它
复杂代码通常可以通过模块化来厘清,还有更多的方法来做这件事,将长条件语句的结果存储到一个变量或两个变量中是一种很好的模块化方法,而没有函数调用的开销。这甚至允许你将它们组成更大的条件,或者在别的地方重用结果。

利用变量来划分逻辑:


valid_user = loogedIn() && hasRole(ROLE_ADMIN)
valid_data = data != null && validate(data)

if (valid_user && valid_data) ...

解决问题的方法应该是每个部分尽可能集中,只影响局部状态,不混淆无关的问题,没有副作用,如果可能的话。编程语言和库经常伴随着它们的问题,将它们抽象出来可以帮助你的代码只关注自己的业务。单一职责原可将代码变成良好的设计。

TDD,当做得正确的时候确实有其好处,但是它也一直强迫人们应用以前不受欢迎的某些原则。现在大家都在谈论纯函数。即使你不做TDD,你应该学习它背后的驱动原则。在新的范式下工作能让你成为一个有韧性的开发人员。

使其离散和可加工
您的计算机和工具可能与您一样难以处理代码,在预处理器和变量的数量与代码的复杂程度之间存在一些相关性。

让我们暂时搁置这些额外构建工具的可能的好处。它们需要您使用特定于领域的语言,例如自定义模板,或复杂和动态数据结构(如散列表)。你的IDE通常不会善于处理这些东西,找到相关的代码段将变得更加困难。

避免使用与IDE不兼容的语言扩展和库。它们对您的工作效率的影响将远远超过更简单的配置或使用更简洁的语法从而节省几个敲键的小好处。


使用ServiceLocator.get('servicename')是一个设计示例,导致与大多数IDE集成不佳。

另一种保持IDE的“集成”方法是避免魔术代码。大多数语言将为您提供更多动态代码的写法。滥用这些功能,例如使用魔术字符串,魔术数组索引和自定义模板语言功能将导致更多的断裂的代码库。一般来说,只有人类才知道意义的功能都会导致你走这条路(IDE不懂这些功能背后意义),而且这是一条艰难的道路,因为如果你的IDE不理解代码,任何重构功能将是无用的,特别是当你想迁移到一个更静态的架构。

使其可读
努力建立一个可预测的架构。你的队友会发现更容易找到他们想要的东西,这将大大减少他们完成一些工作所需的时间。一旦你同意了项目的整体架构结构,使明显的主要元素位于突出。比如使用MVC模式将模型,视图和控制器放在自己的文件夹中,而不是三个文件夹分布在几个不同的地方。

谈到了模块化。还可能有过多的模块化,这通常会使代码更难以定位。你的IDE可能会帮助一些,但是通常你会因为它有太多不相关的代码,或者索引和手动处理问题而忽略库文件夹之间的撕裂。这就不行了。尝试使用较少的库,同时又尽可能多满足您的需求。

库包和工具也可能成为新开发者的障碍。我最近使用EcmaScript 7(babel)构建了一个项目,只是到后来才意识到,我们的初级开发者正在卡住在某个地方试图搞懂它。不要使用大家仍然太难以握住的工具。等待一个更好的时间再用。

使它容易消化
选择好的名字是软件开发中最大的问题之一。构建工具不太可能改进这一点,原因是计算机不能真正知道解决方案背后的原因。你必须记录为什么这么做的原因。对有关的和上下文的变量和函数取名是做到这一点的伟大方法。 传达目的的名称甚至会减少对文档的阅读需要。

在名称中使用前缀是一个很好的方式来给他们添加意义。这是一个惯例,以前是流行的,我认为滥用是导致它没有变得流行的原因。像匈牙利语符号这样的前缀系统最初意在增加意义,但随着时间的推移,它们最终以较少的语境方式使用,例如只是添加类型信息。

最后,保持低循环能降低复杂性。这意味着条件语句的分支数量要尽可能少。每个额外的分支将不仅增加复杂和有害可读性,更重要的是增加你必须跟踪事情的数量。

Writing good code: how to reduce the cognitive loa