This pattern pops up a lot. It looks like a very verbose way to move what would otherwise be separate named methods into a single method and then distinguished by a parameter.
Is there any good reason to have this pattern over just having two methods Method1() and Method2() ? The real kicker is that this pattern tends to be invoked only with constants at runtime– i.e. the arguments are all known before compiling is done.
public enum Commands
{
Method1,
Method2
}
public void ClientCode()
{
//Always invoked with constants! Never user input.
RunCommands(Commands.Method1);
RunCommands(Commands.Method2);
}
public void RunCommands(Commands currentCommand)
{
switch (currentCommand)
{
case Commands.Method1:
// Stuff happens
break;
case Commands.Method2:
// Other stuff happens
break;
default:
throw new ArgumentOutOfRangeException("currentCommand");
}
}
That pattern could be valid if you needed the coupling to be very loose. For example you might have an interface
If you have a method per command then each time you add a new command you would need to add a new method, if you have multiple implementations then you would need to add the method to each Processor. This could be resolved by having some base class, but if the needs diverge you could end up with a very deep class heirarchy as you add new abstraction layers (or you may already be extending another class in with the processor. If it is based on switch’s over the constant you can have you default case that handles new cases appropriately by default (exceptions, whatever may be appropriate).
I have used a pattern similar to this in my code with the addition of a factory. The operations started as a small set, but I knew they would be increasing, so I had a mechanism to describe the command and then a factory that produced CommandProcessors. The factory would generate the appropriate processor and then the single method of that processor would accept the command and perform its processing.
That said if your list of command is fairly static and you don’t need to worry about how tightly things are coupled then the one-method-per-command approach certainly lends itself to much more readable code.