如何用单个函数替换C++中存在重复逻辑的两个相似函数?
解决方案:合并重复工作流+策略模式应用
当然可以用一个通用函数替代这两个重复的workflow,而且这类「固定流程+可变步骤」的场景,正好对应经典的设计模式。咱们来一步步拆解:
1. 用通用函数合并重复逻辑
你会发现,workflow1和workflow2的核心流程完全一致:先执行doThings(),再调用某个业务方法,最后执行doOtherThings()。唯一的差异就是中间调用的方法(method1/method2)和参数不同。
咱们可以把固定流程抽成一个通用函数,把变化的部分作为可调用对象传递进去。在C++里,用lambda表达式是最简洁直观的方式:
#include <functional> // 需要包含这个头文件来使用std::function class MyClass { public: void workflow1(int x) { // 把method1的调用封装成lambda传给通用函数 generic_workflow([this, x]() { method1(x); }); } void workflow2(int x, int y=1) { // 同理封装method2的调用 generic_workflow([this, x, y]() { method2(x, y); }); } private: // 通用工作流函数,接受一个无参的可调用对象 void generic_workflow(std::function<void()> action) { doThings(); action(); // 执行传入的可变步骤 doOtherThings(); } // 原有成员函数保持不变 void doThings() {} void doOtherThings() {} void method1(int x) {} void method2(int x, int y) {} }; int main() { MyClass myClass; int x = 0; myClass.workflow1(x); int y = 2; myClass.workflow2(x, y); }
如果想避免std::function的轻微性能开销,也可以用模板版本的通用函数(更高效):
class MyClass { public: void workflow1(int x) { generic_workflow([this, x]() { method1(x); }); } void workflow2(int x, int y=1) { generic_workflow([this, x, y]() { method2(x, y); }); } private: // 模板版本,接受任意可调用对象 template<typename Func> void generic_workflow(Func&& action) { doThings(); std::forward<Func>(action)(); // 完美转发避免拷贝 doOtherThings(); } // 原有成员函数不变... };
2. 关于「将函数及其参数作为参数传递」
完全可以!上面的lambda表达式本质就是把「函数调用+参数绑定」打包成一个可调用对象,传递给通用函数。除此之外,你也可以用std::bind来绑定成员函数和参数,不过lambda的可读性更好,现在更推荐用lambda。
比如用std::bind的写法(仅供参考):
void workflow1(int x) { generic_workflow(std::bind(&MyClass::method1, this, x)); }
3. 适用的设计模式:策略模式(Strategy Pattern)
这个场景完美匹配策略模式:
- 通用函数
generic_workflow是上下文(Context),它定义了固定的执行流程; method1和method2以及它们的参数绑定对象,就是具体策略(Concrete Strategy);- 通过向上下文传入不同的策略,就能实现不同的业务逻辑,同时复用固定流程代码。
策略模式的核心思想就是将变化的逻辑与不变的逻辑分离,避免重复代码,同时让扩展新的工作流变得更简单——比如以后要加workflow3,只需要新增一个method3,然后在workflow3里调用generic_workflow传入对应的lambda即可,完全不用修改通用流程代码。
内容的提问来源于stack exchange,提问作者sofname
相关产品推荐
相关产品推荐

