I have a list of jobs queued in the database which I need to read from database and execute them in parallel using threading and I have a list of command classes to execute each of those jobs all implementing a common interface (command pattern). but when I retrieve the pending jobs from the database, I will need to instantiate the right command object for each job something like this (in a factory class)
ICommand command;
switch (jobCode)
{
case "A":
command = new CommandA();
break;
case "B":
command = new CommandB();
break;
case "C":
command = new CommandC();
break;
}
command.Execute();
Is there a better way to create the right command object without using a big switch statement like above? OR is there any other pattern for executing the queued jobs?
Solution: solved like this (based on the selected answer). This will do lazy instantiation of the command objects.
public class CommandFactory
{
private readonly IDictionary<string, Func<ICommand>> _commands;
public CommandFactory()
{
_commands = new Dictionary<string, Func<ICommand>>
{
{"A", () => new CommandA()},
{"B", () => new CommandB()},
{"C", () => new CommandC()}
};
}
public ICommand GetCommand(string jobKey)
{
Func<ICommand> command;
_commands.TryGetValue(jobKey.ToUpper(), out command);
return command();
}
}
Client:
var factory = new CommandFactory();
var command = factory.GetCommand(jobKey);
command.Execute();
Most C# command pattern implementations more or less the same as a Java implementation. These implementations usually use a ICommand interface:
and then all command classes are forced to implement the interface. I have no issues with this solution, but personally I don't like creating too many classes and I prefer to use .NET delegates instead (there are no delegates in Java). The Action delegate usually does the trick if only need one method reference:
If your command interface needs more than one methods like:
You can use a wrapper class like this:
or (it doesn't matter which one)
(this one may even implement ICommand if you have legacy stuff using it already. If you use the interface the factory should use the interface instead of the Command class)
With a wrapper like this you are not forced to create a command class for each action you want to support. The following example demonstrates how you can use the wrapper class:
As you can see there is no need to implement the interface even if you have more than one method (Execute, Undo, etc). Please note that the Execute and Undo methods may belong to different classes. You are free to structure your code the way it feels more natural and still can use the command pattern.