Reputation: 415
I know how to implement a Command Design pattern as follows:
public abstract class Command
{
public abstract void Execute(string someString);
}
Say I inherit this ,as an example:
public class ConnectionCommand : Command
{
public override void Execute(string connectionString)
{
...do some stuff here...;
}
}
Problem is to use this ConnectionCommand I need to first instantiate an object, but the commands are context free, so I would prefer to not have to instantiate anything to run the ConnectionCommand's Execute method. (P.S. the ConnectionCommand.Execute() will be run from an event ,in a delegate).
How would I recreate this kind of design pattern but allowing the methods to be statically called?
Upvotes: 3
Views: 1327
Reputation: 43264
Delegates are C#'s built-in implementation of the command pattern. Why re-invent the wheel; use delegates, which support static, pure functions automatically.
So you have an event system and those events invoke delegates. You need those delegates to have state though, without creating instances of some class. That's where closures come in to play. As an example:
public class SomeClass
{
public static CreateCommand(SomeType state, SomeEventHandler eventHandler)
{
eventHandler += (s, e) => MyDelegate(state, s, e);
}
private static void MyDelegate(SomeType state, object sender, EventArgs e)
{
// do something with state, when the event is fired.
}
}
Upvotes: 8
Reputation: 415
http://journal.stuffwithstuff.com/2009/07/02/closures-and-the-command-pattern/
A link to some of Bob Nystrom's stuff. Using closures:
static class Commands
{
// create a command to move a piece
public static Action MovePiece(Piece piece, int x, int y)
{
return () => piece.MoveTo(x, y);
}
}
class Program
{
public static Main(string[] args)
{
// ui or ai creates command
var piece = new Piece();
var command = Commands.MovePiece(piece, 3, 4);
// chess engine invokes it
command();
}
}
A very neat way to do the Command Design pattern in C# using closure and a Factory, similar to an answer above but without state information. Still I've added it for completeness. The Commands.MovePiece can then be subscribed to an appropriate event to get triggered.
Upvotes: 0
Reputation: 6811
I've used a 'CommandProcessor' when I've used this pattern:
class CommandProcessor
{
static void Execute(ICommand command)
{
command.Execute();
}
}
It is then used as such:
CommandProcessor.Execute(new ConnectionCommand {PropertyX = 1, ProperyY = 2});
It works nicely as your processor can effectively employ a 'pipe and filter' pattern to add cross-cutting concerns.
It can be enhanced with generics and overloads for parameters/return values, etc.
Upvotes: 0