1.功能快速迭代
在软件开发的实际工作当中,有时候我们需要开发一个新的大的功能,可以称它叫作长命功能分支(Long lived feature branch),因为有些大功能需要我们花几周甚至几个月来开发,相对应地它的功能分支也会非常庞大。
当整个功能开发完毕后,我们需要把它合并到主分支里面,因为里面代码实在太多了,不可避免地就会出现许多合并冲突。哪怕勉强修正并编译通过,软件里面也很可能隐藏一些不容易发现的Bug,一旦出现排查起来也比较费时间。
通常的办法是我们会把一个庞大的功能分拆成多个小任务,每个任务都建一个的功能分支,当一个任务完成后马上合并到主分支里面。
会出现我们每次把小任务合并到主分支的时候,不小心把完成的功能发布给用户。例如我们在发布V1.2版本的软件时就包含了branch-1分支上的代码,可是整个功能还没有开发完毕,我们并不愿意把这部分代码发布给终端的用户。
那有没有什么办法既能及时合并代码,又能保证主分支可以随时发布呢?有,答案就是使用功能开关组件。
功能开关是软件开发中一种十分实用且功能强大的技术,它允许我们在不改变代码的情况下调整软件的行为。有了它,我们在快速开发的同时,也能放心定期发布新版本。
具体来说,当我们开发每一个大功能时,如果先定义一个功能开关,然后在整个功能开发完毕后再移除它,那么在移除之前,我们提交的任何版本就能避免因为疏忽大意而把未完成的功能发布到终端用户手上。
使用功能开关是保证主分支可以随时进行发布的有效手段。可以说,一个能随时发布的主分支是衡量一个开发环境成熟与否的标准,有两大原因:
- 创建一个名为
config.toml 的文件,定义你的功能开关。例如:
[features]
feature_a = "enabled"
feature_b = "disabled"
feature_c = "enabled"
#include <iostream>
#include <toml.hpp>
void featureA() {
std::cout << "Feature A is enabled!" << std::endl;
}
void featureB() {
std::cout << "Feature B is enabled!" << std::endl;
}
void featureC() {
std::cout << "Feature C is enabled!" << std::endl;
}
int main() {
try {
auto config = toml::parse_file("config.toml");
auto featureAStatus = toml::find<std::string>(config, "features", "feature_a");
auto featureBStatus = toml::find<std::string>(config, "features", "feature_b");
auto featureCStatus = toml::find<std::string>(config, "features", "feature_c");
if (featureAStatus == "enabled") {
featureA();
}
if (featureBStatus == "enabled") {
featureB();
}
if (featureCStatus == "enabled") {
featureC();
}
} catch (const toml::parse_error& err) {
std::cerr << "Error parsing TOML file: " << err.what() << std::endl;
return 1;
}
return 0;
}
2.OEM定制
我们在开发软件的时候会考虑很多功能的实现,但对于不同的用户会有不同的需求,有的用户只需要A功能,不需要且禁止B功能,别的用户只需要B功能,不需要且禁止A功能,不可能为不同的用户开发多个软件,维护成本也会增加,这时候就需要一个软件针对不同的用户进行OEM定制,通过配置文件来实现。
- 首先,创建一个名为
config.toml 的配置文件,内容如下:
[features]
A = true
B = false
#include <iostream>
#include <fstream>
#include <string>
#include <toml.hpp>
void featureA() {
std::cout << "Feature A is enabled." << std::endl;
}
void featureB() {
std::cout << "Feature B is enabled." << std::endl;
}
int main() {
toml::table config;
try {
config = toml::parse_file("config.toml");
} catch (const toml::parse_error& err) {
std::cerr << "Error parsing config.toml: " << err.description() << std::endl;
return 1;
}
bool featureAEnabled = toml::find<bool>(config, "features", "A");
bool featureBEnabled = toml::find<bool>(config, "features", "B");
if (featureAEnabled) {
featureA();
} else {
std::cout << "Feature A is disabled." << std::endl;
}
if (featureBEnabled) {
featureB();
} else {
std::cout << "Feature B is disabled." << std::endl;
}
return 0;
}
可以根据需要在 config.toml 中添加更多的功能配置。例如:
[features]
A = true
B = false
C = true
D = false
- 可以利用 TOML 配置文件来管理软件功能的启用和禁用,从而为不同的用户提供个性化的定制。这样的实现不仅降低了维护成本,还提高了代码的灵活性和可重用性。根据不同用户的需求,可以简单地修改配置文件,而无需更改源代码。