根据调用方/上下文专门化函数的行为

Specializing a function's behavior depending on caller/context

本文关键字:函数 专门化 上下文 调用      更新时间:2023-10-16

假设您有一个程序,其中两段旧代码执行相同的工作,只是它们在两个不同的上下文中执行:一个在GUI中执行,另一个在API中执行。假设你想重构它们以便池化/合并代码,这样你只有一个代码为API和;GUI。

但是有一个问题:代码片段并不是100%相同。与API相比,GUI必须做一些额外的工作(例如,在GUI中,所做的每个更改都必须通过撤消/重做系统,但在API中没有,因为它不使用撤消/重做)。

所以说你可以合并80%的代码行为,但是你剩下的20%必须专门用于API和GUI(即。

你怎么解决这个问题?

我想到了:

  • 创建一个公共函数,其中通过回调注入专门的代码(例如;子);
  • 或:创建一个模板化的公共函数,调用其他模板化的子函数。由于这些子函数也是模板化的,因此它们可以具有模板专门化,一种专门化用于GUI;API。通用模板化函数的参数化将确保调用正确的子函数的模板专门化。

但这些解决方案都不满足我:

  • 给一个函数传递几个回调函数真的会让它的签名很快变得混乱;

  • 第二种解决方案,当你开始模板化时,你可能最终会模板化大部分涉及的函数(这当然取决于你的代码,但在我的情况下,这是一个问题)。

还有其他想法吗?

听起来唯一的区别是GUI做了API没有做的事情。如果API做了一些GUI没有做的事情,那就会影响答案。

,

如果有任何方法重构你的代码,使所有的特殊情况的东西发生在同一个代码块,你可以把代码块放在一个函数的GUI,然后调用"通用"函数后。

void GUI_Func()
{
    //do some special GUI stuff
    common_func();
}
void common_func()
{
    //do stuff common to both the GUI and the API
}

,

然而,在我看来,你似乎有必要在整个函数中分散不同的功能。

你提到了撤消/重做系统。这些代码可以移动到一个负责处理撤销和重做的类中吗?在这种情况下,您可以在template<typename UndoRedo>上模板函数。对于GUI表单,你将在你的Undo/Redo类中传递,对于API表单,你将在一个带有匹配接口的空类中传递;尽管没有任何功能。在编译时,空类操作将是无操作的,并且可能被编译器忽略。

我不确定我理解你的代码复杂到什么程度,但对于某些情况,比如这些,我会传递一个可选的布尔参数,当它为真时,会使额外的东西发生。同样,我不完全确定这是否适合这种情况。在这种情况下,GUI将调用参数设置为true的公共函数,API版本将调用参数设置为false的公共函数。

在你的地方,我会考虑委托,你把所有与UI相关的代码放在这个委托类中