首页 > Coding > C++ API 中的版本控制

C++ API 中的版本控制

2017年1月6日 发表评论 阅读评论

1 应该提供 API 版本号信息

这个类提供了单独返回当前版本号的主、次、补丁版本号的的访问函数。它们返回各 define 定义的值。GetVersion 方法向用户返回友好的字符串版本号信息。 当用户相比较版本号时,他们通常不关心版本号本身,而是想知道某些特性在该版本的API中是否存在。HasFeature() 方法 不是告诉用户哪个版本的 API 引入了哪些特性,而是让亿们直接测试某个特性是否可用。

2 软件分支策略

一般的大型项目通常会涉及到某种形式的分支策略,这需要同步开发、维护不同的软件版本发布。我们将讨论为项目选择分支策略和方针时需要考虑的一些事项。

2.1 分支策略

每个软件都需要一条 trunk (主干)代码路线,它是cppAPIversion软件项目源码
的持久库。对于对于每次版本的发布
,可以从主干进行。每次新版本的开发,可以从主干的代码添加分支,而使主干的代码不受开发的影响而保持稳定。右图是一种常见的分支策略。

2.2 API与并行分支

在API发布以后,对其所有的更改都应该表现为一个连续的过程,即不发布不兼容的非线性版本的API,一个版本的API应该是前一个版本功能的严格超集。在大型项目中,通常会有几条并行的代码分支在进行同时开发,这就会产生若干个并行维护的API版本。因此,工作在不同并行分支上的团队互不引入不兼容的特性是非常重要的。下列方法可以帮忙处理这种潜在的问题:

  • 制定开发分支的目标: 项目通常有开发分支和发布分支。只要保证不直接在发布分支上进行个性,就能减少由于未将当前版本的修改合并到主干而导致API在下一个版本丢失的可能性。如果需要发布分支上修改的API,那么应该先将它提交到主干,并进行合并。这适用于发布分支的修改。
  • 经常合并到主干中。 对于API的任何修改,要么在主干上进行,要么尽早合并到主干中。
  • 审查过程。独立的API审查委员会应该在公有API发布之前对其进行监督和审查,以确保API不存在冲突或无法向后兼容的修改。

这些解决方案试图将API的准确性保持在主干代码中,而非将各个修改散落在多个分支中。

3 API的生命周期

API的维护不同于一般的软件产品。这是因为API开发具有额外的约束力:不能破坏已有客户的程序。如果API进行修改,可能会破坏已有的客户的程序。API是一种有契约:你必须确保遵守你制定的规则。 上图给出了一个典型的API生命周期简图。在其生命周期内,version2最听重要的事件是初始发布。在这个关键点之前,对设计和接口作出的重大修改都是可以接受的。但是在初始发布后,一旦用户使用了你的API进行开发,就需要承诺提供向后兼容性,你能够修改的范围受到了限制。 API开发有4个常见的阶段。

  1. 发布前:初始发布前,API可以遵循标准的软件开发周期,包括需求收集、计划、设计、实现、测试等。实际上还可以向用户发布API早期版本以获得反馈和建议。这时的版本号可以使用 0.x ,以表明API仍处于活跃地开发中,在正式版本发布前可能会有大的修改。
  2. 维护:API发布后仍然可以修改,但是为了维护向后兼容性,只能增加新的方法或类,以及修复已有方法实现中的错误。为确保修改不破坏兼容性,好的方式是在新版本发布前进行回归测试和API审查。
  3. 完成:在某个时间点,可以认定API已经成熟,不应对接口做进一步的修改。这个阶段,API的稳定性是最重要的,通常只会修复某些错误。
  4. 弃用:有些API最终会达到其生命周期的终点,此时它们会被放弃使用。当API不在提供应有的服务,或有新的、不兼容的API取代原的的API,原来的API会被弃用。弃用的API不应在任何新的开发中使用,已有的客户程序也应该放弃使用这些API.

4 如何维护向后兼容性

4.1 添加功能

一般来说,添加新的类、接口不会对已有的API进行改变,不会破坏已有的代码。这对于API兼容性来说是好的。例外的是,给抽象基类添加新的纯虚成员函数是不向后兼容的。

客户所有的派生类都必须定义这个新方法的实现,否则它们就不能被实例化。变通的方法是为添加到这个抽象类中的新方法提供一个默认实现,即把其定义为虚方法而不是纯虚方法。

4.2 修改功能

当我们需要修改一个API,有很多技巧可以提高API的兼容性:

4.2.1 可选参数与返回值

为方法添加可选参数是向后兼容的:

同样,修改原本不需要验证的返回值也是向后兼容的:

4.2.2 添加名称类似的函数

这种方法在 C 风格API中比较常见。在API中引入一个名字不同的函数,同时重构旧的方法的实现,使之调用新的方法。

4.2.3 修改功能而不修改方法签名

这种情况一般为了修复API中的错误。也可以在API的实现中使用外部变量来控制API的逻辑:

上面这段代码中,V1.1的API和V1.0的逻辑是一样的。如果客户需要使用修改后的功能(do thing B),则可以对使用 SetDoSth() 方法来进行逻辑控制。

4.3 弃用功能

弃用功能一般是指建议用户不要使用某API.为维护兼容性,该API仍然可以使用,但是会以某种方式向用户发出警告,使用户有时间来处理其代码。例如在 MSVC 中,使用 fopen() 会得到警告,提示用户使用更安全的 fopen_s() . 当准备弃用API时,需要在API中说明弃用它的理由,并提供解决方案,如使用某API进行替代。

当用户调用 GetName() 方法时,编译器会输出警告消息,告诉用户该方法已经弃用。

  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.