团队拓扑:如何驯服邪恶的依赖


大型组织中的软件开发团队之间的依赖关系是一个大问题。多年来,我看到了许多应对这一问题的不同策略——有些成功,有些则比较麻烦。 

处理依赖关系最常见的问题是,它们经常被忽略或简化;有时,一刀切的万能框架被错误地应用:解决依赖关系总是取决于具体情况。这就是为什么我们需要全面看待依赖关系。如果我们要解决我喜欢称之为“邪恶依赖关系”的问题——之所以这样称呼,是因为它们能够破坏和撤销大量的工作和努力——那么我们必须适当地结合策略和实践。

在这篇文章中,我将解释如何做到这一点。

依赖的负面后果
 不过,首先,让我们明确提醒自己解决依赖关系为何如此重要:它可能导致上市时间延长,甚至可能导致项目失败。依赖关系导致的额外等待时间和项目交接增加意味着团队需要更多时间来开发功能并将其带给客户。 
 
考虑有时需要的上下文切换依赖关系;这可能会对个人和团队的生产力和绩效产生负面影响。 
 
总而言之,我们可以将依赖关系描述为对这些领域产生负面影响: 
 

  • 交货时间 
  • 团队绩效 
  • 动机

 
鉴于这些领域对于有效软件交付的重要性,值得将依赖关系视为真实而有形的风险。事实上,这种重新定义可能会有所帮助,并改变团队处理它们的方式——我认为这可以成为正确解决这些问题的第一步。
 
将依赖关系重新定义为风险
 将依赖关系重新定义为风险有助于给予依赖关系应有的关注。它还可以引导您采用更明确的结构来处理它们——遵循风险管理流程。换句话说,管理依赖关系应该包括:
 
  • 规避风险:通过消除依赖关系来最小化依赖关系 
  • 降低风险:减少其负面影响
  • 风险承受:适当协调

 
基于这三项风险管理活动,我们创建了以下模型,以构建掌握邪恶依赖关系所必需的实践。

最小化依赖
 
首先,让我们看看如何最小化依赖关系。这可能是最难实现的,但却是最有效的措施。首先要从源头开始发现依赖关系。
 
识别依赖关系的来源
 
依赖关系通常由以下三种原因引起:
 

  • 要求: 互相依赖且无法由不同团队独立实现的待办事项。
  • 工程过程:工程过程中的连续任务(例如产品设计、编码和测试)分布在多个团队中,显然无法独立执行。
  • 软件组件:在更改软件系统的一部分时,必须考虑这一更改对其他组件和其他团队的影响。

 
消除依赖关系
 一旦我们确定了依赖关系的来源,我们就可以尽早采取措施消除它们。团队组成及其关注领域是减少依赖关系的决定性杠杆。如果处理得当,上述来源对团队之间的依赖关系的影响很小。 
 
  • 要求:待办事项应更注重目标和客户价值。这是因为与以输出为导向的待办事项(如任务和组件更改)相比,它们往往更加独立。进行更改的一种方法是围绕这些待办事项(如功能或客户需求)组织团队。这样做的另一个好处是,它还应该能够更加关注客户。
  • 工程流程:创建具备所有必要技能和能力的跨职能团队。这样做意味着团队能够更好地独立处理端到端的所有事务;简而言之,他们不再依赖上游或下游任务。
  • 软件组件:让团队专注于软件系统的特定部分(例如模块或微服务),这些部分与系统的其他部分松散耦合。这可确保变更对其他团队的影响较小。领域驱动设计是实施此方法时的一种有用方法。

 
如果你遵循这些建议,你就会得到《团队拓扑》一书中描述的内容作为“流程一致的团队”。随着客户需求、业务战略和架构的不断发展,团队需要重新调整,以最大限度地减少依赖性。
 
值得注意的是,即使拥有最佳的流程一致团队,如果目标是最大化客户价值,也不可能完全消除所有依赖关系;它们是不可避免的。本文的其余部分将讨论如何管理这些残留和持久的依赖关系。

减轻依赖关系的影响
 
如果我们可以减轻依赖性造成的风险,那么我们就可以减少它们的(负面)影响。这种影响的程度通常与开发给定功能所需的时间和精力有关。因此,如果团队有效地合作解决依赖关系(减少中断和上下文切换),负面影响应该会小得多且易于管理。下面介绍的以下做法可以帮助您更好地应对依赖关系。
 
通用标准
 
举个例子,两个团队想要快速就一个界面达成一致。如果两个团队之前没有见过面,并且有不同的协作习惯、使用不同的技术或对如何定义界面有不同的看法,那么设计该界面肯定会花费相当多的时间(也可能会带来一些挫折)。因此,共同的标准会非常有帮助。一起工作的团队应该对他们的架构原则、工程和部署实践以及共同的工作方式有共同的理解。要做到这一点需要一个良好的流程。 
 
当然,一种方法是自上而下地规定标准。然而,这会削弱团队的自我效能——结果可能会损害士气和积极性。更有效的方法是让使用  轻量级治理的团队形成共享标准。开放空间技术、实践社区或征求意见等实践将有助于以适合团队敏捷文化的方式建立这种共识。这些实践促进了超越团队界限的协作。它们支持知识交流,并更好地实现制定共同标准所需的跨团队决策。 
 
整体产品焦点
 
团队面临的另一个挑战是就解决依赖关系的共同时间表达成一致。让我们以前面的例子为例:团队希望就界面设计达成一致并实现它。然后,两个团队都需要安排何时进行什么工作。如果团队以不同的方式确定优先级,结果可能是灾难性的;这可能会导致长达数周甚至数月的等待时间。 
 
为了解决这个问题,两个团队需要通过对给定任务对整个产品的重要性的共同理解来保持一致。换句话说,整个产品关注是必不可少的。这可以通过多种做法来实现,最值得注意的是拥有单一的产品待办事项适用于所有团队或根据精益价值树进行协调。此外,诸如总体回顾、共同市政厅和涉及多个团队的运行软件的联合演示等做法有助于促进对共同开发联合产品的理解。
 
解除依赖关系的实践
 
团队拓扑方法还建议采用将阻塞依赖关系转变为非阻塞依赖关系的做法。团队应该有能力满足自己的需求,而不是等待另一个团队完成任务。发展技能和平台以支持自助服务应该可以解除更多依赖关系并最终改善流程。工程平台就是一个很好的例子。 
近年来,许多工程实践的出现使得团队更加独立,例如功能切换消费者驱动合同、具有折旧策略的版本控制 API、事件驱动的通信基础设施即代码。所有这些实践都减少了组件之间的耦合,并实现了更大的异步性。它们还有助于将责任转移到最适合解决特定问题的个人或团队,这意味着可以将功能的更改保存在一个地方。团队应该熟练掌握这些实践,以减少依赖关系对流程的影响。
 
指导代码更改
 
当一个团队需要与另一个团队合作开发某个功能时,通常是因为另一个团队需要更改他们的代码才能实现整个功能。 
但是,如果团队可以自己更改代码会怎样呢?为此,团队需要访问代码。更重要的是,团队还需要拥有足够的知识来浏览代码并进行必要的更改。高质量的代码是这种方法的先决条件。此外,通用标准也可以提供帮助,例如编码指南。 
但是,请记住,浏览未知代码非常具有挑战性。您仍然在一定程度上依赖其他团队的知识。为了解决这个问题,应该组织知识转移——团队间配对是一种特别有效的方法。
 
不断最小化
 
与其学习更改另一个团队的代码,更好的方法可能是重构并简单地删除依赖项。如果两个团队解决了依赖项并更改了系统的设计,那么将来他们可以更加独立地工作。他们需要很好地了解依赖项对流程的一般影响,才能明白为什么这种方法是必要的。双方都必须明白,改进整个系统比局部优化更好——为了实现这种行为,团队需要紧密合作。  
 
传播知识
 
如前文所述,知识依赖性可能会阻碍开发过程。这就是为什么认真思考如何在团队之间传递知识很重要。
例如,假设一个团队想要实现一个新功能,但需要依赖另一个团队,而该团队之前做过类似的事情,并拥有相关的专业知识。很多时候,团队一开始就试图获取所需的知识,而不是联系其他团队,这是非常低效的。
因此,培养一种分享文化很重要,这样团队才能走出去与其他团队交流。良好的知识共享做法可以帮助快速解决这种依赖关系,并可能减少团队受阻或陷入任务困境的时间。
 
协调实践
 
即使我们采取一些措施来减轻依赖关系的影响,也不可能完全消除它们。那些仍然存在的依赖关系仍然需要得到适当的管理。这就是协调的作用所在——协调依赖关系有助于团队就需要做的事情达成一致。整个产品焦点支持这种对齐。 
 
有两种不同的策略:
 

  1. 必要的工作是按顺序安排的。例如,一个团队开始创建或更改他们的部分代码;完成后,另一个团队继续。
  2. 团队同时一起工作。两个团队在同一迭代中规划他们的工作,并在一段时间内进行协作。

 
通常,团队会采用第一种策略,因为他们觉得这很自然。这也意味着他们可以尽量减少与其他团队成员的互动。但实际上,由于集成较晚,他们可能会发现问题,最终需要相互互动来解决问题(即使在流程后期)。 
 
而第二种策略则要求开放。两个团队共同发现新事物,反馈周期保持较短,环境切换减少,因为两个团队已经在相同的环境中工作。 
 
无论选择哪种策略,无论是按顺序还是同步,都需要团队协调他们的日程安排。有一种做法非常著名。通过大房间规划,多个团队一起规划即将到来的迭代,以实现共同目标,例如发布或程序增量。这通常是一场漫长的会议。SAFe 框架将这种做法称为 PI 规划。 
 
但是,这种方法并不总是最有效的。幸运的是,还有几种替代方案:
 
  • 滚动式前瞻性规划,团队会提前展望几次迭代并预测即将到来的范围 — 然后来自各个团队的代表会协调如何整体管理。依赖关系矩阵可以在这里提供帮助。

  • 对于较大的功能,建议多个团队聚在一起进行密切协作。这在功能改进过程中甚至更早就开始了。多团队改进和多团队规划的实践源自 LeSS 知识体系(大规模 Scrum)。在这里,团队应该一起开改进会议和规划会议。在规划中,每个团队都会得出自己的迭代待办事项。在迭代过程中,两个团队的工作紧密相关,并且有密切的合作。

 
结论
 正如我们所见,依赖关系就是风险。消除依赖关系是第一步,但无法消除的依赖关系需要通过有效的协调来缓解和解决。为此,产品开发组织需要熟练掌握将团队之间的依赖关系降至最低的策略。 
 
我们应该认识到,组织永远无法完全消除所有依赖关系。这就是为什么他们必须准备好调整团队拓扑结构并开发跨团队协作的新方法,特别是如果他们想要更加以客户为中心的话。