A name to generalize the function? Is this an anti-pattern?

What is the name to pass an argument to a function to choose what the function does?

For example:

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

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

      

Vs:

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

      

+2


source to share


8 answers


This example can be seen as Premature Generalization

Extra options. There is only one case where adding a parameter is a generalization of a function or class body: if that parameter is "active" (like an object or type or function pointer) and some special details about how the function or class works, the code represented by that parameter. Examples are sort order predicate sort function and allocator parameter for template or container class constructor. In addition, a parameter can be a generalization of code that calls or uses a class only if that code is not concerned about the actual value of the parameter.

Code



  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();
  }

      

0


source


In general, this can be viewed as an anti-pattern, since the individual methods are simpler and more explicit. However, some situations can change this opinion. Two examples:

Front controller

All templates Front Controller

work as follows (Struts or later): the call is made by a centralized method with parameters; it is later sent to the correct handler (defined by one of the parameters). The point here is to apply generic code before (and after, possibly for exceptions) many specific codes.

The problem is not that this type of code is being executed, but for this in your own code. If it's in the framework code (already written, well tested, etc.), that's ok. Examples are all interception technologies such as Spring ..



Command

The pattern Command

might be pretty close:

  • the identifier can identify the command to be executed;
  • then you will find the correct code: in the command template it is an object, so you can use the map to find the object that matches the id
  • execute code: in the Command pattern, all of these objects have a common method, so calling it is generic, no switch needed.
+4


source


Constructs like these often appear along with loops that repeat over all values. In this case, it is a masked loop-switch pattern .

But this is not an anti-pattern per se. If you do not know the parameters in advance, such a design may be valid.

+3


source


I named the parameter that you pass in "action" or "verb". I have not seen this called a template. What you are not showing is an inevitable statement switch

that ... I guess why you call it antipater.

You can think of this as a bad implementation of the command pattern . And there is an article on wikipedia about function objects which is also a bad implementation.

Before object-oriented languages ​​were widespread, we did things like this to group functions into objects and often called them "dispatching". (This name was included in the template world with a different thing.)

+3


source


Communication management .

I heard about this in a presentation by Jim Weirich. In general, the method will have a "flag" parameter that will control which algorithm to use.

See my notes (with some links) on Grand Unified Theory of Software Design .

+2


source


This is not necessarily an anti-pattern!

Even when the f () function is one big switch, it can be a convenient place where individual "tokens / verbs / instructions / atoms" of a particular "language" are processed (or rather, "sent for processing"). In addition, the f () function can also introduce logic to decide how to dispatch a specific verb based on the runtime context. This ability to late bind text / data verbs to specific methods in a simple, centralized manner is important, although in other cases, using polymorphic and introspective features of OO languages ​​for this purpose may be more appropriate.

Edit: See KLE's answer as it reflects the idea that this is a template. KLE also refers to Command and Front Controller templates, which are the same / similar.

+1


source


This will be the goal of refactoring by creating separate method names for each case and placing any generic code in a commonly called method.

0


source


I would call it a dispatcher since it will probably call more specific code based on the parameter (s).

Functions that are too general can be bad: difficult to use, difficult to maintain, difficult to debug. Their overly general nature makes it difficult to assert pre- and post-conditions and invariants. However, dispatchers sometimes use it. This is one way to provide extensibility β€” sometimes it’s a more practical way to use traditional templates.

0


source







All Articles