持续集成-功能分支和功能开关

1. 问题

功能开发完成后,因为某种原因不进行发布。通常采用两种策略:采用功能分支的方式进行开发,延迟合并和发布。另一种是方式是,代码进行合并和发布,通过功能开关来控制该功能是否被用户感知。

2. 功能分支

功能分支的使用:通过对每个功能创建一个feature分支,功能完成后合并到release分支或master分支。

2.1 功能分支的好处

  • 开发阶段,同时进行各功能的开发,相互独立,彼此不受影响
  • 大功能或远期功能开发,不受版本发布的影响

2.2 功能分支的问题

  • 分支时间长:合并时容易产生冲突
  • 分支多:合并分支时,容易遗漏
  • 违背持续集成:分支不能持续的进行合并,不能尽早发现问题。即便feature分支进行了测试和功能验证,不能保障release分支没有问题。仍需要对release分支进行回归测试。
  • 其他场景:修改公共功能或进行重构时,会涉及其他分支中大量引用。合并时会产生大量的编译错误,也可能需要多个分支进行方法调用的修改。团队可能会为了避免产生未知的错误,而减少重构。而重构在软件开发过程中是必不可少的,不做重构,技术债就会越积越多。

3. 功能开关

功能开关主要用于主干开发,通过布尔类型的配置项控制软件功能是否对外部可见。这要求某个功能的各个相关模块共同读取该功能的控制开关。

3.1 功能开关的使用

一个功能可能会涉及多个方面,如前端页面、后端功能、数据库等。对于该功能的每个方面可能都需要进行控制。

3.1.1 功能控制开关

系统需要在配置文件中提供相关功能的配置项,其他相关模块读取该配置项。以Springboot项目为例,在application.properties文件中:

featureX.isActivated=true

3.1.2 前端页面

通过JSP、Vue、React等技术开发的前端,可通过页面标签的可见性来控制该功能是否可用

<h1 v-if="featureXIsActivated">Vue is awesome!</h1>

3.1.2 后端功能

  • 在程序的入口控制功能的调用,如controller中,判断配置项的值来控制返回值。
......
protected ModelAndView handle(HttpServletRequest request, HttpServletResponse
 response, Object command, BindException bindingResult) throws Exception {
     if(!applicationConfig.getMessageAsBoolean("featureXIsActivated")) {
          return new ModelAndView("404.jsp");
     }
     //normal logic
}
......
  • 在程序逻辑中控制某一新功能

3.1.3 数据库

  • 重点设计数据库的兼容性

3.2 功能开关的好处

  • 修改配置即完成了功能发布
  • 必要时,可以控制功能降级
  • 紧急情况下,可快速限制某一功能的访问

3.3 功能开关注意事项

  • 功能独立控制,不相互依赖

4. 总结

功能开关能够减少分支合并,但功能开关也会增加管理的成本。对于已经明确上线的功能,后续要去除配置项及判断语句,以减少维护开关的成本。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容