Answers:
功能标记是一种工程设备,可用于避免长期存在的分支和产品开发中的冲突。这是在面向对象语言的上下文中如何使用它来帮助开发人员在处理一种新产品的同时就特定产品功能进行协作的方法。只要存在“接口”的概念,该解决方案也可以在非面向对象的上下文中使用。(请参阅 OCaml模块系统。)
为了说明的目的,我们假设有一个工具可以显示有关存储在数据库中的数据的报告。该代码实现了用于执行请求的DatabaseClient类。随着数据集的增长,很明显,某些替代数据布局将提高应用程序性能。因此,爱丽丝(Alice)将开发新版本的数据库客户端(DatabaseClient),该版本能够从布局改进的结构中检索数据,而鲍勃(Bob)将维护历史数据库客户端。
通过以下步骤,Alice和Bob可以在寿命短的分支机构上进行协作,同时最大程度地减少冲突。
爱丽丝将DatabaseClient重命名为DatabaseClient_v1,并创建一个名为DatabaseClient的委托类,该委托类使用对象DatabaseClient_v1并实现一个名为DatabaseClientInterface的接口。(如果可能,此DatabaseClientInterface应该是代码伪像,但鸭子类型的语言并不总是支持此功能。)
Bob回顾了Alice在1中所做的更改,并且知道他的维护工作应该在DatabaseClient_v1上进行。
爱丽丝在应用程序中引入了一个新的配置标志,该标志控制着DatabaseClient委托的行为并实现了DatabaseClient_v2占位符,该类实现了DatabaseClientInterface,其方法都引发了“未实现”异常。
此后,Alice和Bob可以在没有显式同步的情况下进行协作,因为在各自的迭代中编写的代码受DatabaseClientInterface的约束。这样可以最大程度地减少因并发工作而导致冲突的风险。
Alice的迭代可能非常短,例如实现测试,实现方法,甚至部分地这样做,因为在生产中,没有选择要使用的代码,并且不需要完全起作用。应该配置自动测试套件,以便DatabaseClientInterface始终使用DatabaseClient_v1,而在本地运行测试套件时或在自定义CI设置中,Alice可以轻松切换至DatabaseClient_v2。一旦一切准备就绪,单个提交就可以通过更新控制DatabaseClient委托的配置值来执行更改 。
嵌入式软件界经常在应用程序代码本身(例如#define
/ #ifdef
语句)和/或构建工具配置文件(例如)中使用构建时标志makefile
。
构建标记可以类似的方式不仅用于功能,还可以用于所有类型的代码重构,迁移,调试支持等)。它们允许在集成分支中提交部分或未验证的更改,而不会破坏构建或导致分支中已经使用的功能/项目出现退化。以连续集成的方式非常适合处理点修复以及较大/风险/缓慢的进度更改(否则将需要长寿命的分支)。
但是除了验证已经存在的分支代码以进行回归之外,还可以对新代码执行进度/稳定性验证。为此,需要切换构建时间标志。
切换标志的一种方法是,在同一分支的CI系统的单独验证管道中使用(如果它支持这种功能)补丁文件,该标志将在切换到该分支之前应用于单独的工作区。建立。将在此工作空间中构建一组不同的工件,然后进行验证。
另外,可以从主集成分支中提取一个寿命较长的功能分支,但是该功能分支中唯一的更改是切换标志。由于这一微小的更改,功能分支可以非常快速地自动同步-实际上非常接近主集成分支。在此分支上执行单独的CI将不再需要初步的补丁文件。即使在很长一段时间内也无法进行这样的功能分支。
也有可能在主集成分支中创建新的构建工件,这些构建工件实际上只是现有构建工件的克隆,但标志已切换。这样,在主分支中,既不需要初步的补丁文件,也不需要功能分支来验证新代码。