假设我有一个只应该定义一些常量才能执行的函数。以下哪一项会更好
选项1:将所有函数调用包装在if块中:
if(defined('FOO_BAR_ENABLED')) {
foobar();
}
我想这样意图更清晰,但每次调用函数时都需要检查常量。
选项2:检查函数本身的常量:
function foobar() {
if(!defined('FOO_BAR_ENABLED')) {
return;
}
//do stuff
}
这种方式需要更少的代码行,并且必须检查常量。但是,我发现在没有实际执行任何操作时看到对此函数的调用会让人感到困惑。想法?
答案 0 :(得分:10)
我可以建议将函数重命名为FoobarIfEnabled(),然后检查函数吗?
从一个伟大的语言不可知的answer to one of my own questions中大量窃取,在编程时我们有以下问题:
如果您在功能外进行检查,最终可能会在一个地方错过它。如果你想改变行为,你必须找到它被调用的所有地方并修复它。这是一个违反原则1的维护噩梦。通过在名称中添加“IfEnabled”或类似名称,现在它不仅正确而且也很清楚。你怎么能打败它?
除非最终速度不令人满意并且您已将此识别为瓶颈(不太可能),否则不要担心性能。
我建议你按照上面的链接阅读,因为这是一个非常有用的答案,让我有很多想法。
答案 1 :(得分:2)
选项3:
void maybe_foobar() {
if(defined('FOO_BAR_ENABLED')) really_foobar();
}
void really_foobar() {
// do stuff
}
在美好的一天,我会想到比“可能”和“真实”更好的名字,但这取决于功能的作用以及为什么它可以关闭和开启。
如果在没有定义FOO_BAR_ENABLED的情况下没有任何人可以有效地“做东西”的情况,那么我会选择你的选项2(并且可能调用函数do_stuff_if_possible
而不是{{1} },如果名称foobar
导致混淆是否调用它需要实际做任何事情)。如果它总是对“做东西”有效,但有些用户恰好这样做是有条件的,那么我会选择3。
选项1将导致您复制并粘贴代码,这几乎总是一个坏符号。
[编辑:这是选项4,我怀疑它是过度工程,但你永远不知道:
foobar
然后你用:
来称呼它void if_enabled(string str, function f) {
if (defined(str + '_ENABLED')) f();
}
显然,您的语言处理函数的方式存在一些问题,以及是否有任何方法可以通过if_enabled('FOO_BAR', foobar);
传递任意参数和返回值。]
答案 2 :(得分:1)
if
的条件是否属于职能部门的职责范围?是否有一个用例来调用没有if
的函数?
如果总是需要检查条件,我会把它放在函数中。遵循DRY原则:不要重复自己。另一个可能有用的讽刺是SRP - 单一责任原则 - 做一件事,做得好。
答案 3 :(得分:1)
在头文件中,如果foobar总是使用相同数量的参数,
#ifdef ENABLE_FOOBAR #define maybe_foobar(x) foobar(x) #else #define maybe_foobar(x) #endif
如果foobar可以获取可变数量的参数,则不确定如何在C ++或更早的C语言中执行此操作。
(刚刚注意到与语言无关的标签。好吧,上面的技术是我在其工作的语言中建议的;也许使用内联函数用于具有那些但缺少宏的语言)。
答案 4 :(得分:0)
选项2,减少代码并确保定义常量,如您所建议的那样。
答案 5 :(得分:0)
由于这显然只与foobar()函数一起使用,因此选项2应该是您的选择。这意味着测试只位于一个地方,您的代码更具可读性。