这是一篇关于软件开发中认知负荷(Cognitive Load)的文章,主要观点、关键信息和重要细节如下:
引言(Introduction):
- 众多软件开发相关的流行语和最佳实践大多失败,需要更基础的东西,而认知负荷是软件开发中的一个基本人类限制,我们应时刻关注代码中是否嵌入了过多的认知负荷。
认知负荷(Cognitive Load):
- 认知负荷是开发者完成任务所需的思考量,普通人工作记忆中大约能容纳 4 个信息块,超过这个阈值就难以理解代码。
- 减少项目中的认知负荷很重要,认知负荷与中断有关。
认知负荷的类型(Types of cognitive load):
- 内在(Intrinsic):由任务的固有难度引起,不可减少。
- 外在(Extraneous):由信息的呈现方式引起,可大大减少,文章主要关注此类认知负荷。
复杂条件语句(Complex conditionals):
- 复杂的条件语句会增加认知负荷,引入有意义的中间变量可降低认知负荷。
嵌套的 if 语句(Nested ifs):
- 嵌套的 if 语句会增加认知负荷,早期返回可使我们只关注正常路径,释放工作记忆。
继承噩梦(Inheritance nightmare):
- 继承结构复杂会增加认知负荷,应优先使用组合而不是继承。
太多浅模块(Too many small methods, classes or modules):
- 过多的浅模块(接口复杂但功能小)会使项目难以理解,应追求深模块(简单接口和复杂功能)。
- 以 UNIX I/O 为例,简单的接口隐藏了大量复杂性,但易于使用。
单一责任原则(Responsible for one thing):
- 不应为了遵循“一个模块应只负责一件事”的原则而创建过多浅模块,模块应只对一个用户或利益相关者负责。
- 记住一个地方的更改可能会引发不同业务流的连锁反应是很困难的,应关注认知负荷。
太多浅微服务(Too many shallow microservices):
- 浅微服务架构不好,行业正在走向“宏服务”,过度细分的浅分离可能导致分布式单体,增加诊断难度和认知负荷。
- 精心设计的单体比一堆微服务更灵活,维护成本更低,只有在需要单独部署时才考虑添加网络层。
功能丰富的语言(Feature-rich languages):
- 语言中的大量特性会增加认知负荷,应限制选择,使语言特性相互正交。
- 以 C++为例,其特性增加了认知负荷,程序员需要记住很多规则。
业务逻辑和 HTTP 状态码(Business logic and HTTP status codes):
- 在后端返回自定义的 HTTP 状态码会增加前端和测试人员的认知负荷,应直接在响应体中返回自描述的代码。
- 应避免使用模糊的术语,如区分“认证”和“授权”,可使用更简单的术语。
滥用 DRY 原则(Abusing DRY principle):
- 过度遵循“不要重复自己”原则会导致组件之间的紧耦合,增加认知负荷,阻碍组件的替换和修改。
- 不应为了避免重复而导入大型、笨重的库,应尽量自己编写简单的代码。
与框架紧密耦合(Tight coupling with a framework):
- 过度依赖框架会增加新开发者的学习成本和认知负荷,框架可能会成为新需求的约束。
- 应将业务逻辑与框架分离,以框架库的方式使用框架,让新贡献者能够从第一天开始就创造价值。
分层架构(Layered architecture):
- 分层架构往往会增加认知负荷,抽象层过多会导致追踪问题困难,改变存储等操作会带来很多问题。
- 不应为了架构而添加抽象层,只有在有实际需求时才添加,抽象层并非免费,会占用工作记忆。
领域驱动设计(Domain-driven design):
- 领域驱动设计常被误解,应关注问题空间而不是解决方案空间,避免创建过多的外在认知负荷。
- Team Topologies 框架比领域驱动设计更有助于分担认知负荷。
示例(Examples):
- 提供了一些简单易懂的架构示例,如标准的 CRUD 应用架构、Instagram 的早期架构等。
- 应让初级开发者参与架构审查,以识别需要改进的地方。
熟悉项目中的认知负荷(Cognitive load in familiar projects):
- 熟悉项目并不意味着简单,熟悉项目中的“聪明”技巧可能会给其他人带来学习负担。
- 新开发者加入项目时,若在 40 分钟内仍感到困惑,说明代码需要改进。
结论(Conclusion):
- 应减少除工作本身固有的认知负荷之外的任何认知负荷,不要给同事增加不必要的认知负荷。
总之,文章强调了在软件开发中关注和减少认知负荷的重要性,通过具体的示例和对比,提出了多种减少认知负荷的方法和原则。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。