通过组件化加速协作和敏捷开发

Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019

你的产品成功,你的组织正在增长,是时候纵向扩展代码库,以匹配此成功。 在单个产品的单个代码库中横向扩展过去 2-3 个团队时,你可能会发现自己会提出如下问题:

  • 我的团队如何有效地共享可重用组件?

  • 如何实现使功能团队能够在不介入其他团队的工作的情况下快速循环访问?

  • 如何实现让我的团队能够自主地循环访问适合他们的节奏?

任何阶段的 Teams 都可以从考虑这些问题中获益。 如果你是一个具有旧代码库的已建立团队,你可能会提出这些问题,因为系统要求你提供的价值比以往更快。 无论你的情况如何,组件化都可以帮助你构建一个可扩展到团队大小和当今开发速度的代码库。

本文探讨通过 Azure Artifacts 进行二进制组合如何帮助你管理和共享外部依赖项、开源软件以及独立共享组件。

组件和组合

组件化是将产品划分为不同的组件并将其组织到不同的组件的过程。 大多数 .NET 项目已经有一些组件的概念,其形式为解决方案中的项目。 例如,基本网站可能包含前端组件、数据访问组件和模型/数据存储组件。

源组合

随着产品的增长,解决方案和项目模型可能会效率低下。 集成需要更长的时间,而且更难合并,生成速度变慢,组件开始从单个项目发展到多个项目。 通常,这是团队开始将这些相关项目集分解为单独的解决方案的点。

一旦你超越了一个解决方案,你如何组件化就成了一个有趣的问题。 我们从源组合开始,其中每个组件都通过 Visual Studio 中的项目引用进行引用。 只要源位于单个合成边界中,源组合就可以:单个源存储库中的单个解决方案。

遗憾的是,当涉及多个解决方案时,这些项目引用开始分解。 此时,当解决方案 A 依赖于解决方案 B 时,它必须引用解决方案 B 生成的二进制文件(如 DLL),这是 二进制组合

因此,这些二进制文件现在需要生成并提供给解决方案 A,然后才能成功生成。 可通过多种方法实现此目的:

  • 可以将它们检查到源代码管理中。 根据源代码管理系统,二进制文件可以快速膨胀存储库的大小,减缓检查超时和常规存储库性能。 如果开始在分支中工作,多个团队最终可以在不同的版本中引入相同的二进制文件,从而导致具有挑战性的合并冲突。

  • 或者,可以在文件共享上托管它们,尽管此方法具有某些限制。 文件共享缺少用于快速查找的索引,它们将来不会提供保护,无法覆盖版本。

包组合

包解决了引用二进制文件的许多难题。 可以让解决方案 B 将其二进制文件生成为 NuGet 包,而不能将其检查到源中,另一个解决方案 A 可以使用。 如果解决方案 A 和解决方案 B 作为单独的组件进行维护,其中 A 和 B 之间的同时更改很少,则包组合是管理 B 上的 A 依赖项的好方法。包组合允许 B 自行循环访问,而 A 可在 A 的计划允许时从 B 获取更新, 它允许多个团队循环访问和更新解决方案 B,而不会影响解决方案 A(或其他解决方案 C 或 D)。

但是,包组合确实附带了自己的一组挑战。 到目前为止,我们已经研究了一个简单的示例。 将包组合缩放到大型代码库(如 Windows 或必应)的大小可能会导致一系列挑战:

  • 了解依赖项关系图中组件中中断性变更的影响非常具有挑战性。

  • 钻石依赖项 可能会成为敏捷性的重要障碍。 在菱形依赖项中,组件 B 和 C 都依赖于共享组件 A,而组件 D 则依赖于 B 和 C。当组件 A 引入具有重大更改的新版本时,如果 B 更新到新版本,但 C 不更新,则 D 不能在不引入依赖项冲突的情况下接受 B 的更新。 在此简单示例中,与 C 的对话可能是解决冲突所需的所有内容。 然而,在复杂的图形中,钻石可以快速变得无法解决。

  • 当需要对使用包组合的两个组件应用修改时,开发人员的迭代周期会大大变慢。 如果更新了组件 A,则它需要重新生成、重新打包和重新发布它。 随后,组件 B 必须更新到最近发布的版本,以验证组件 A 中所做的更改。使用源组合(允许同时生成组件 A 和 B)将持续为开发人员提供更快的迭代周期。

应使用的内容

一般来说,我们看到大型团队在使用组合策略的混合体时最成功。 为了帮助确定适合你的代码库的内容,请首先映射产品的依赖项关系图,并开始将组件分组为相关组件集。

例如,你可能拥有构成框架的组件集合,以及构成面向用户的服务的另一组组件。 然后,对于每个相关组件组,请提出以下问题:

  • 是否可以在为团队建立的集中预测频繁检查?

  • 单个团队是否负责整个集?

  • 对于单个集,是否有共享发布节奏?

在我们的经验中,我们发现,使用 源组合 对单个团队或一组相关团队处理的相关项目最为有效。 相反, 二进制组合 对开源软件、外部依赖项(来自遥远或隔离的团队的组件)和独立的共享组件有利。