认知负荷决定了微服务或单体


这篇文章主要讨论了在软件架构设计中考虑团队认知负荷的重要性。

  • 根据团队的能力和需求,可以选择单体架构或微服务架构。
  • 单个团队适合使用单体架构,多个团队适合使用微服务架构。

文章还介绍了认知负荷的三种类型:内在认知负荷、外在认知负荷和合理认知负荷。

根据团队的专业知识和能力,以及架构的沟通边界和工作分配等因素,提出了一些建议。同时还强调了减少冗余认知负荷的重要性,以及如何在团队间进行有效沟通。

总之,文章认为在软件架构设计中,应该根据团队的认知负荷来做出合适的决策。

原文摘要:

  • 与其在单体架构或微服务架构之间做出选择,不如设计出适合团队最大认知负荷的软件
  • 如果您只有一个团队,请考虑调整架构,使其与团队的能力相匹配。倾向于单体、内聚和模块化架构。
  • 如果您有多个团队,可以考虑采用微服务或类似类型的架构,这样他们就可以独立工作。
  • 并非所有的认知负荷都是相同的。不同类型的认知负荷会影响团队能够交付的高质量成果的数量。企业应努力减轻或消除内在和外在的认知负荷,使团队的认知负荷主要是相关的。
  • 单个团队和多个团队架构之间的交流边界类型有很大不同。单个团队通过代码库、文档、讨论和设计会议进行交流的方式得到了优化。而多个团队则可以通过精心设计的应用程序接口(或库)进行交流,从而抽象出各自领域的复杂性。

如何确定认知负荷能力
让我们来看看心理学家约翰-斯韦勒(John Sweller)所定义的三种认知负荷类型,以及了解这些类型如何帮助我们设计与认知能力水平相匹配的软件架构,并分配适当的工作量:

1.内在认知负荷
这是指团队对所处理的领域有多少专业知识。如果您的团队负责创建一个 ML 愿景项目,但团队中没有人有任何人工智能方面的经验,那么他们在学习这一领域时的内在认知负荷最初会非常高。理想情况下,团队应该在与他们的专长基本一致的领域开展工作,但也要留出一定的发展空间,以保持刺激性。有一点内在认知负荷是好事,因为工程师们喜欢提高技能,但过多的内在认知负荷会造成严重的延误,并让他们对能否尽快交付高质量的成果感到焦虑。

  • 单一团队

尽管一个团队可以是跨职能的,并拥有不同学科的专业知识,但这也有一个上限。如果团队在技能方面存在巨大差距,无法实现所需的目标,可以考虑为他们提供必要的培训和时间,使他们能够迎头赶上。

如果你的项目需要太多领域的专业知识,你就有可能把团队变成一群各自擅长不同领域的人,这很可能会使他们独立工作,而不是作为一个团队工作,从而降低他们的成果质量。

  • 多个团队

拥有多个团队可以为您提供更广阔的空间,让更多的人能够分工协作,同时也可以为您提供更多的专业知识选择。作为一个组织,您可能需要考虑采取一些策略来减少内在认知负荷,比如为每个团队分配不超过一个复杂领域的任务,同时提供培训或设立扶持团队,帮助其他团队在特定领域取得更好的成绩。例如,一个 SRE 团队可以帮助其他团队理解 SLO 和一般可观察性。

建议:

  • 如果你只有一个团队可以为你的愿景工作,而他们的专业技能与你要解决的问题并不一致,那么可以考虑通过为他们提供培训来提高他们的能力。
  • 不要为一个团队分配过多的领域,否则他们就有可能成为不作为一个团体一起工作和学习的个人集合。
  • 拥有多个团队可以让您利用更多的专业知识来扩大软件架构的范围。为每个领域安排合适的团队来完成任务,并在需要时通过培训来提高技能,或让其他团队来培训和协助他们的专业技能。

2.外在认知负荷
这些都是团队需要做的,但对工作成果没有直接贡献的事情。外来认知负荷的发生可能有多种原因,其中许多原因可能无法避免或耗费时间来解决,从而影响整个公司。例如,一个团队被乏味的基础架构任务、乏味的公司流程、琐碎的工作、等待其他团队完成的任务、公司范围内累积的技术债务所困扰--所有这些都是无关的认知负荷,对结果没有直接贡献。因此,无关的认知负荷是最不可取的认知负荷,因为它会在交付过程中产生过多的摩擦。

除了影响组织的外在认知负荷外,架构类型在某些情况下也会增加外在认知负荷:

  • 单个团队

将单个团队的工作拆分为多个微服务,有可能会增加额外的认知负荷,表现为代价高昂的沟通界限,从而使团队的工作支离破碎。

通过工作进行交流是工程交流的最佳形式,但无论是跨团队交流还是同一团队内的交流,都会采取不同的形式。跨团队协作的理想沟通边界是设计良好的应用程序接口(或库!)。但团队内部的交流却并非如此,因为所有成员都熟悉他们正在研究的领域,因此团队内部的抽象并不那么重要,反而会造成额外的认知负担。在这种情况下,清晰的代码、文档、设计和讨论才是沟通的驱动力。

将一个团队的工作分割成多个微服务,每个微服务都有自己的应用程序接口(API),这样会大大增加团队的工作量,因为团队必须对这些应用程序接口进行良好的设计、用户友好的操作和文档记录,而且团队的工作可能会被分割到多个存储库和不必要的边界中。在这种情况下,最好在单一代码库中采用模块化方法,以保持团队内部的一致性和专注性。

  • 多个团队

当有多个团队时,将架构拆分为微服务,可以让他们有更多时间以应用程序接口的形式实现精心设计的通信边界,不再是无关的认知负荷。由于这些应用程序接口将被其他团队使用,因此有两大优势:

它减少了不同团队为完成工作而不断相互交流的需要。

它使其他团队能够自助服务于另一个团队的工作抽象。
它减轻或消除了他们的额外认知负担,因为他们不需要对每个领域都过于熟悉,只要他们知道如何使用应用程序接口就可以了,而应用程序接口必须设计合理、直观。

在这种情况下,应用程序接口可以减少其他团队的认知负荷和不必要的沟通,帮助每个团队都能进入工作流程,从而使组织保持良好运转。

但是,如果您将领域划分给多个团队,并且没有使用优雅的应用程序接口或其他自助服务工具来正确定义通信边界,那么您很快就会发现,每个团队都在不断地与每个人通信,试图了解对方的领域以完成自己的工作。这种情况远非理想,而且会产生大量无关的认知负荷。

建议:

  • 要确保减轻或最好消除所有无关的认知负荷,需要工程设计人员和领导的共同努力。具体做法包括简化流程、减少 "剃光头"、以应用程序接口的形式抽象领域供其他团队使用、以不产生多余通信渠道的方式设计架构等。如果暂时无法减少或消除无关的认知负荷,那么在给团队分配工作时就必须考虑到这一点。过多的无关认知负荷会限制团队成果的数量(甚至可能影响质量),并可能导致倦怠。
  • 一个团队开发多个微服务,可能会引入额外的无关工作,表现为通信边界和团队内部工作的碎片化。更可取的做法可能是在一个模块化的整体上开展工作,然后在必要时进行拆分。
  • 团队间的交流应主要通过自助工具来完成,无论是 API、库、CLI 还是其他任何可行的方式。过多的沟通会造成摩擦,当太多的团队在不必要的情况下互相交流时,就会损害流程。

3.新的认知负荷
真正的认知负荷来自于解决与团队工作领域相关的问题,它能带来流动状态、开发人员的总体幸福感和成果质量。这种认知负荷大多是积极的,前提是团队不能在太短的时间内承担过多的目标。你能减轻的内在和外在工作越多,你的团队就能专注于更重要的工作。

  • 单一团队

如果只有一个团队,在将架构设计分配给该团队之前,应考虑缩小其目标范围。一定要考虑到他们需要处理的无关认知负荷量。请记住,将复杂的微服务架构分配给一个团队本身就会增加额外的认知负荷,即使没有不良工具、技术债务或企业流程或孤岛带来的摩擦给团队带来额外的认知负荷。

与其让团队过度扩张,直到他们精疲力竭或无法高质量地交付功能,还不如将目标缩小到团队能够安全、充分地交付的范围内。您可以根据需要随时增加容量,团队也可以随时将他们的单体模块化,以便日后在必要时将其拆分。

  • 多个团队

另一方面,如果您拥有多个团队,那么您可以考虑将您的架构拆分成微服务或类似的东西,这样团队就可以在各自的领域独立工作。这比每个人在一个单体或一个巨大的共享代码库中一起工作要好,因为在单体或共享代码库中,每个人都要进行超负荷的持续沟通。

当多个团队合作交付软件时,请确保您的团队拓扑结构反映了您的软件架构,并将设计良好的应用程序接口作为团队沟通的一种形式。这将使团队更容易抽象出其领域的复杂性,并减少整个组织交付工作所需的谈话量。

建议:

  • 如果只有一个团队,则应采用模块化的单体架构。设计适合团队能力的软件,以便他们能够提供高质量的成果。始终将内在和外在的认知负荷考虑在内,因为它们会减少团队能够处理的相关认知负荷量。
  • 如果您有多个团队和复杂的需求,请使用微服务或架构,以便团队通过精心设计的应用程序接口轻松交流和抽象其领域。切勿为每个团队分配一个以上的复杂领域。


总之:

  • 根据团队的认知负荷调整软件架构,单一团队可采用单体化、协同和模块化架构,多个团队可采用微服务或类似的架构。
  • 不同类型的认知负荷会影响团队交付质量成果的能力,组织应该努力减少或消除内在和外在的认知负荷,以便团队主要面对与领域相关的认知负荷。
  • 单一团队通过代码库、文档、讨论和设计会议进行沟通,而多个团队更适合通过良好设计的API(或库)进行沟通,以抽象出各自领域的复杂性。