将参数传递给函数以选择函数的作用的名称是什么?
例如:
enum {
DoSomething,
...
};
void f(FunctionType a);
f(DoSomething);
....
f(DoSomethingElse);
Vs的:
void DoSomething();
....
void DoSomethingElse();
答案 0 :(得分:4)
通常,人们可以将其视为反模式,因为单独的方法更简单,更明确。但是,某些情况可能会改变这种观点。两个例子:
所有Front Controller
模式都是这样的(Struts或更高版本):使用参数调用集中式方法;它稍后被分派到正确的处理程序(由其中一个参数标识)。这里的要点是在许多特定代码之前(以及之后,可能是例外)应用公共代码。
问题不在于此类代码是否会执行,而是在您自己的代码中执行此操作。如果它是在框架代码中(已经编写,经过良好测试等),那很好。 示例是所有拦截技术,如Spring ..
Command
模式可能非常接近:
答案 1 :(得分:3)
这些构造经常与遍历所有值的循环一起出现。在那种情况下,它是伪装的loop-switch pattern。
但这本身并不是一种反模式。如果您事先不知道参数,那么这样的设计可能是有效的。
答案 2 :(得分:3)
我调用了你在“动作”或“动词”中传递的参数。我没有看到这个命名为模式。你没有展示的是不可避免的switch
陈述,这是 - 我假设 - 为什么你称它为反模式。
你可以认为它是command pattern的糟糕实现。维基百科有一篇关于function objects的文章,它也是一个糟糕的实现。
在面向对象的语言流行之前,我们做了类似这样的事情,将函数分组到对象中,并经常将其称为“调度”。 (这个名称已被包含在模式世界中,但却有不同的东西。)
答案 3 :(得分:2)
控制耦合。
我在Jim Weirich的演讲中听到过这个消息。通常,该方法将具有“标志”参数,该参数控制要使用的算法。
在Grand Unified Theory of Software Design查看我的笔记(包括一些参考资料)。
答案 4 :(得分:1)
它不一定是反模式!
即使f()函数是一个大开关,它也可以是处理特定“语言”的单个“标记/动词/指令/原子”(或者更确切地说“发送以进行处理”)的便利位置。此外,f()函数还可以引入逻辑来决定如何基于运行时上下文调度特定动词。这种以简单,集中的方式将文本/数据动词后期绑定到特定方法的能力很重要,即使在其他情况下,使用OO语言的多态和内省特征来实现此目的可能更合适。
编辑:请参阅KLE的回复,因为它回应了这是一种模式的想法。 KLE还提供相同/相似的Command和Front Controller模式的参考。
答案 5 :(得分:0)
这将是重构的目标,为每个案例创建单独的方法名称,并将任何公共代码放入常用的方法中。
答案 6 :(得分:0)
我称之为Dispatcher,因为它可能会根据参数调用更具体的代码。
过于一般的功能可能很糟糕:难以使用,难以维护,难以调试。它们过于笼统的性质使得很难确定前后条件和不变量。尽管如此,调度员确实偶尔使用它们。它是提供可扩展性的一种方式 - 有时它是传统模式的一种更实用的方式。
答案 7 :(得分:0)
此示例可被视为Premature Generalization
额外参数。 只有一种情况是添加参数 构成功能或类体的概括:如果这样 参数是“活动的”(作为对象或类型或函数指针) 以及函数或类如何工作的一些特殊细节 此参数表示的代码。这些例子是一种排序 排序函数和分配器的顺序谓词参数 容器类模板或构造函数的参数。额外的 参数可以构成调用的代码的泛化 只有当这段代码不打扰时,才能使用或使用该类 此参数的实际值。
代码
enum command{ start, stop };
void f_command(command do){
if( do==start )
f_start();
else
f_stop();
}
void f(){
f_command(start);
f_command(stop);
}
Vs的
void f(){
f_start();
f_stop();
}