为多个地区和客户拥有一个代码库
Having one code base for multiple regions and clients
上下文:
我们使用 ASP.NET MVC 为美国地区的一个客户构建了一个数据密集型应用程序,现在我们正在慢慢转向 ASP NET Core。我们需要为加拿大开发类似的版本,我们的方法是维护两个不同的代码库,即使 UI 有 70% 相同。
问题:
两个代码库似乎可以维护,但如果必须更改通用组件,则最终会做双重工作。现在我们有来自多个地区的多个客户,UI 可能因客户和地区而略有不同,我们对如何仅使用一次代码库来构建这样的应用程序感到有些困惑。
我不确定什么是可维护和可扩展的方法。
一种方法是让 UI 由能够显示和隐藏组件的规则引擎提供支持。从部署的角度来看,这种方法的可维护性如何?
还有什么其他方法可以解决这个问题?
我能想到的主要做法是:
分离代码库和发布管道。这似乎是你目前的做法。
- 优点:
- 独立发布 - 像发布其他团队为美国所做的对加拿大的更改并不令人意外
- 可能更简单的代码库 - 更少的配置,更少的“if (region == 'CANADA')...”
- 独立 QA - 如果您只测试一个环境,自动化测试会简单得多
- 缺点:
- 正如您已经注意到的那样,重复工作
一个代码库,更改配置驱动。
- 优点:
- 一处改变
- 缺点:
- 许多开发人员同时处理相同代码的机会更高
- 你可能会以可怕的方式结束 'ifs'
- 分离发布管道可能非常棘手。如果您对加拿大进行更改,则需要针对美国测试所有内容——这可能需要大量工作,具体取决于 QA 自动化水平和测试场景的复杂性。另外,您是否仅仅因为加拿大有人想将按钮颜色更改为绿色而发布美国版?如果你这样做,那你就是在浪费时间。如果您不这样做,那么可能未经测试的更改会在下一个美国版本中堆积起来。
- 如果你有其他地区,这个代码很快就会变得复杂 - 许多人只是扔东西让他们的地区工作,你最终得到意大利面条代码。
使用通用的、可配置的模块分离代码库。
这可能包含您认为不太可能因地区而异的任何内容:具有核心逻辑的 Nuget 包、具有 javascript 的 npm 包、前端样式等
- 优点:
- 如果处理得当,您可以两全其美 - 单独的发布管道和单独的(简单)区域特定代码
- 您可以更改通用模块并决定when/if将每个区域分别更新到最新版本
- 缺点:
- 更多的基础设施工作 - 每个应用程序和每个包都需要一个发布管道
- 调试和理解在应用程序中使用的打包代码很棘手
- 更改公共模块中的某些内容并在您的应用程序中对其进行测试是一件痛苦的事情 - 您必须转到公共存储库,进行更改,测试它,创建 PR,合并它,等待包构建和发布,升级您的应用程序...然后您发现更改是错误的。
我参与过这样的项目,但问题总是存在——如果你让它超级可配置,它就会变得不可读和过度设计。如果将其分开,则必须在很多地方进行更改,并且在很多地方维护诸如单元测试之类的东西是一场噩梦。
由于您已经从方法 1 开始,并且您提到其他区域即将到来,我建议您采用当前的策略并慢慢抽象通用部分以分离回购(转向第三种方法)。
我认为使此类更改更容易的最重要的部分是适当水平的测试自动化 - 无论是对于您的应用程序还是对于您创建它们时的通用模块。
我可以给你的一条建议是务实。一定程度的重复是可以的,特别是如果替代方案是一个复杂的规则引擎,没有人理解也没有人愿意接触,因为它无处不在。
上下文: 我们使用 ASP.NET MVC 为美国地区的一个客户构建了一个数据密集型应用程序,现在我们正在慢慢转向 ASP NET Core。我们需要为加拿大开发类似的版本,我们的方法是维护两个不同的代码库,即使 UI 有 70% 相同。
问题: 两个代码库似乎可以维护,但如果必须更改通用组件,则最终会做双重工作。现在我们有来自多个地区的多个客户,UI 可能因客户和地区而略有不同,我们对如何仅使用一次代码库来构建这样的应用程序感到有些困惑。
我不确定什么是可维护和可扩展的方法。 一种方法是让 UI 由能够显示和隐藏组件的规则引擎提供支持。从部署的角度来看,这种方法的可维护性如何?
还有什么其他方法可以解决这个问题?
我能想到的主要做法是:
分离代码库和发布管道。这似乎是你目前的做法。
- 优点:
- 独立发布 - 像发布其他团队为美国所做的对加拿大的更改并不令人意外
- 可能更简单的代码库 - 更少的配置,更少的“if (region == 'CANADA')...”
- 独立 QA - 如果您只测试一个环境,自动化测试会简单得多
- 缺点:
- 正如您已经注意到的那样,重复工作
- 优点:
一个代码库,更改配置驱动。
- 优点:
- 一处改变
- 缺点:
- 许多开发人员同时处理相同代码的机会更高
- 你可能会以可怕的方式结束 'ifs'
- 分离发布管道可能非常棘手。如果您对加拿大进行更改,则需要针对美国测试所有内容——这可能需要大量工作,具体取决于 QA 自动化水平和测试场景的复杂性。另外,您是否仅仅因为加拿大有人想将按钮颜色更改为绿色而发布美国版?如果你这样做,那你就是在浪费时间。如果您不这样做,那么可能未经测试的更改会在下一个美国版本中堆积起来。
- 如果你有其他地区,这个代码很快就会变得复杂 - 许多人只是扔东西让他们的地区工作,你最终得到意大利面条代码。
- 优点:
使用通用的、可配置的模块分离代码库。 这可能包含您认为不太可能因地区而异的任何内容:具有核心逻辑的 Nuget 包、具有 javascript 的 npm 包、前端样式等
- 优点:
- 如果处理得当,您可以两全其美 - 单独的发布管道和单独的(简单)区域特定代码
- 您可以更改通用模块并决定when/if将每个区域分别更新到最新版本
- 缺点:
- 更多的基础设施工作 - 每个应用程序和每个包都需要一个发布管道
- 调试和理解在应用程序中使用的打包代码很棘手
- 更改公共模块中的某些内容并在您的应用程序中对其进行测试是一件痛苦的事情 - 您必须转到公共存储库,进行更改,测试它,创建 PR,合并它,等待包构建和发布,升级您的应用程序...然后您发现更改是错误的。
- 优点:
我参与过这样的项目,但问题总是存在——如果你让它超级可配置,它就会变得不可读和过度设计。如果将其分开,则必须在很多地方进行更改,并且在很多地方维护诸如单元测试之类的东西是一场噩梦。 由于您已经从方法 1 开始,并且您提到其他区域即将到来,我建议您采用当前的策略并慢慢抽象通用部分以分离回购(转向第三种方法)。 我认为使此类更改更容易的最重要的部分是适当水平的测试自动化 - 无论是对于您的应用程序还是对于您创建它们时的通用模块。
我可以给你的一条建议是务实。一定程度的重复是可以的,特别是如果替代方案是一个复杂的规则引擎,没有人理解也没有人愿意接触,因为它无处不在。