过度概括函数的名称?这是反模式吗?

时间:2009-09-30 14:13:24

标签: language-agnostic anti-patterns

将参数传递给函数以选择函数的作用的名称是什么?

例如:

enum {
   DoSomething,
   ...
};
void f(FunctionType a);

f(DoSomething);
....
f(DoSomethingElse);

Vs的:

void DoSomething();
....
void DoSomethingElse();

8 个答案:

答案 0 :(得分:4)

通常,人们可以将其视为反模式,因为单独的方法更简单,更明确。但是,某些情况可能会改变这种观点。两个例子:

前端控制器

所有Front Controller模式都是这样的(Struts或更高版本):使用参数调用集中式方法;它稍后被分派到正确的处理程序(由其中一个参数标识)。这里的要点是在许多特定代码之前(以及之后,可能是例外)应用公共代码。

问题不在于此类代码是否会执行,而是在您自己的代码中执行此操作。如果它是在框架代码中(已经编写,经过良好测试等),那很好。 示例是所有拦截技术,如Spring ..

命令

Command模式可能非常接近:

  1. 标识符可以标识要执行的命令;
  2. 然后找到正确的代码:在命令模式中,它是一个对象,因此您可以使用地图来查找与标识符对应的对象
  3. 执行代码:在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();
  }