最佳实践?#ifdef
(或由运行时配置或任何其他编译时或运行时条件有条件地包含或有条件地注入相同接口的单独实现)!
在任何版本控制系统中,将并行版本作为分支来维护是一件很痛苦的事情。最好使用适当的条件编译或运行时配置技术来维护并行版本。
请记住,如果将分支 A 合并到分支 B,然后将分支 B 合并回分支 A,则两个分支将完全相同。这是 3 路合并的内在属性。这正是你想要的功能分支,但它完全不适合为不同的客户维护并行版本。
为了为不同的客户保留版本,请改用条件编译。
- 在面向对象的代码中,您通常可以拥有具有通用逻辑的基类和具有特定于该变体的逻辑的每个变体自定义派生类,这些逻辑要么有条件地包含在项目中,要么有条件地实例化。
- 大多数编程语言都支持某种形式的条件编译,Java 是一个明显的例外。
这种方法允许每个人通过对所有变体运行测试或由持续集成服务器构建和测试所有变体来立即检查他们没有破坏任何一个变体的任何功能。
你提到PHP。那里没有编译步骤,因此配置将只是运行时。我可能会创建一个包含特定于客户的覆盖的目录,这些覆盖将有条件地包含在适当的模板中。
注意:我目前正在开发一个 C++ 项目,该项目以这种方式为 20 多个客户定制,并且可以很好地扩展。我们没有每个客户的确切代码,而是我们有一组可选的功能,并且不同的子集被运送给不同的客户。这使得测试所有特性变得更容易一些,因为我们可以构建一个最大的变体并对其进行测试。当您发展到大量功能时,这会有所帮助,特别是如果您的项目需要很长时间才能构建(我们的持续集成构建运行大约一个小时,每晚构建 8 小时,构建所有客户变体需要超过一整天)。