开发者该用单一代码库还是多代码库管理代码?

译文
开发 架构
代码库就像其使用者,多种多样、特色鲜明、各有趣味。但是,几乎所有代码库都有一个共同点:代码库会逐渐变大。随着时间的推移,团队壮大,需求增长,最终结果是更多的开发人员编写更多的代码处理更多的任务。虽然删除大段代码不乏乐趣,但终究难挡代码库整体变大的步伐。

如果你负责组织的代码库架构,那么如何以可扩展的方式管理这种增长,这个问题早晚要应对。有两种常见的架构方案可供选择:

一种是“多代码库”架构,我们将代码库分成越来越多的小代码库,以小团队或项目为边界。另一种是“单一代码库”,即维护一个不断变大的大型代码库,内含许多项目和库的代码,多个团队围绕该代码库进行协作。

多代码库方案看起来容易实现,最初可能很诱人,我们只要在需要时创建更多的代码库就好了!我们几乎不需要任何特殊工具,且可以让每个团队在管理代码方面拥有更大的自主权。

遗憾的是,实际上,多代码库架构常常导致代码库脆弱、不一致且难以更改。这进而助长了工程部门本身的孤岛现象。相比之下,单一代码库方案反而是一种更好、更灵活、更具协作性的长期扩展解决方案。

为什么会这样?代码库架构中的难点涉及在有依赖项的情况下管理代码更改,反之亦然。而在多代码库架构中,代码库通过已发布的版本化工件(artifact),使用来自其他代码库的代码;这样一来,更改传递愈发困难。

具体来说,当我们作为代码库A的所有者需要对所使用的代码库B进行一些更改时,会发生什么?首先,我们得找到代码库B的看门人,说服他们接受并发布新版本的更改。然后,在理想情况下,有人会找到代码库B的所有其他使用者,将它们升级到这个新版本,然后重新发布。现在我们必须找到那些初始使用者的使用者,升级并针对新版本重新发布等等,循环往复,不厌其烦。

但谁来做所有这些工作?他们将如何找到所有这些使用者?毕竟,依赖项元数据驻留在使用者端,而不是被使用者端,没有简单的方法来回溯依赖项。当一个问题的归属并不直接、解决方案又不明显时,往往会被忽略,因此实际上不会出现回溯工作。

短时间内可能没什么关系,因为其他代码库固定到了早期版本的依赖项。但这种舒适状态很难长久,因为迟早有些使用者会被集成到一个可部署的工件中,到时就不得不有人为该工件选择单一版本的依赖项。因此,我们最终会遇到由一个过去的团队引起的传递版本冲突,它就像埋入代码库的定时炸弹,如果另外某个团队需要将代码集成到生产环境中,它会引爆炸毁。

如果这个问题很眼熟,那是由于它是臭名昭著的“依赖地狱”(dependency hell)问题的内部版本,该问题通常困扰着代码库的外部依赖项。在多代码库架构中,第一方依赖项技术上来说被视为第三方依赖项,即使它们碰巧由同一家组织编写和拥有。因此,如果是多代码库架构,我们基本上选择了面临大规模扩展的依赖地狱。

单一代码库与之形成了对比:所有使用者都在同一源代码树中,因此找到它们就像使用grep一样简单。又由于没有发布这一步,所有代码共享一个版本(由当前提交表示),因此以传递且同步地更新使用者流程上简单直观。如果我们的测试覆盖率良好,就可以清楚地知道我们什么时候做对了。

当然,“简单直观”与“容易”不一样:同步升级代码库本身可能并非易事。但这就是代码更改的本质。没有哪种代码库架构可以消除工程问题中不能化简的部分。但是单一代码库现在至少强制我们把必要的难题处理掉,也就不会在以后造成不必要的困难。

多代码库架构在未来往往将依赖地狱外化到其他人身上,这是与康威定律(Conway’s Law)相关的一个更宽泛的问题:“任何设计系统的组织都会形成这样一种设计,其结构与组织沟通结构亦步亦趋”。反过来也大致如此:组织的结构往往是这种沟通所围绕架构的副本。在这种情况下,分散的代码库架构会促进工程部门本身的分裂,代码库设计最终让组织各自把关和职责分散,而不是齐心实现共同目标,因为这些共同目标没有在架构上加以表示。单一代码库支持并能以温和的方式实现组织统一:每个人都在单一代码库方面进行协作,这正是组织成功构建统一产品所需要的沟通渠道。

单一代码库并不是灵丹妙药。它也确实需要合适的工具和流程来保持性能规模化和工程有效性。但借助合适的架构和工具,你就可以确保代码库和组织各自有机统一,以规模化表现蒸蒸日上。

原文标题:The monorepo approach to code management,作者:Benjy Weinberger

责任编辑:华轩 来源: 51CTO
相关推荐

2011-07-18 09:10:30

Linux 3.0微软

2020-06-05 14:48:11

零代码低代码开发

2023-12-30 16:30:29

开发者工具Vite

2019-11-20 09:25:03

Visual Stud编程语言

2024-09-09 00:01:00

腾讯开源代码

2020-06-03 18:10:46

GitHub代码库前端

2011-04-01 15:09:18

Symbian诺基亚

2024-08-12 09:05:00

AI训练

2019-01-08 09:55:45

GitHub代码开发者

2020-11-13 15:40:18

React前端Recoil

2020-10-09 11:50:10

ReactRecoil前端

2021-05-07 05:38:02

微软Edge浏览器

2023-11-01 13:37:38

Golang代码

2017-12-22 07:31:41

2014-03-13 11:08:42

结对编程代码审查

2010-01-22 09:09:00

Linux代码开发

2015-08-19 13:35:56

编程代码审查开发者

2024-10-12 09:38:53

2013-08-15 13:27:00

Windows 8.1

2022-06-30 07:48:06

Dooring低代码零代码
点赞
收藏

51CTO技术栈公众号