Command pattern encapsulates a request as an object and gives it a known public interface. Command Pattern ensures that every object receives its own commands and provides a decoupling between sender and receiver. A sender is an object that invokes an operation, and a receiver is an object that receives the request and acts on it.
Let us examine this pattern with the help of most commonly used electronic gadgets at home, a VCR, a DVD player and an Universal Remote to start and stop them.
Follow steps mentioned below to create an implementation of Command pattern in C# :
Step 1. Command Interface
Create a Command interface with Execute method. All the concrete Command objects must provide implementation of Execute method as it would be called to perform the requested operation.
//File Name : ICommand.cs
using System;
public interface ICommand
{
void Execute();
}
Step 2: Command Objects
Create Command objects implementing Command interface needed for this example. These objects would act as Receivers and execute requested functionality through Execute method. For this example, we will consider four command objects, namely DVDPlayCommand- command to play DVD, DVDStopCommand - command to stop DVD and similarly VCRPlayCommand- command to play VCR and VCRStopCommand- command to stop VCR.
//File Name : DVDPlayCommand.cs
using System;
public class DVDPlayCommand : ICommand
{
public DVDPlayCommand()
{
}
public void Execute()
{
Console.WriteLine("DVD Started.");
}
}
//File Name : DVDStopCommand.cs
using System;
public class DVDStopCommand : ICommand
{
public DVDStopCommand()
{
}
public void Execute()
{
Console.WriteLine("DVD Stopped.");
}
}
//File Name : VCRPlayCommand.cs
using System;
public class VCRPlayCommand : ICommand
{
public VCRPlayCommand()
{
}
public void Execute()
{
Console.WriteLine("VCR Started.");
}
}
//File Name : VCRStopCommand.cs
using System;
public class VCRStopCommand : ICommand
{
public VCRStopCommand()
{
}
public void Execute()
{
Console.WriteLine("VCR Stopped.");
}
}
Step 3: The Invoker or Sender Object
The invoker or Sender object is the one which invokes the requested functionality.
Create a Remote object which would act as an invoker and would invoke operation requested by Client. This object has a method called Invoke which takes an ICommand object as parameter and invokes its Execute method.
//File Name : Remote.cs
using System;
public class Remote
{
public Remote()
{
}
public void Invoke(ICommand cmd )
{
Console.WriteLine("Invoking.......");
cmd.Execute();
}
}
Step 4: And the Client Object
Create a Client object, which would instantiate a Remote object and all the commands client is interested in and then would pass them to Remote object to invoke those operations.
//File Name : Client.cs
using System;
public class Client
{
public Client()
{
}
public static int Main(String[] args)
{
//Instantiate the invoker object
Remote remote = new Remote();
//Instantiate DVD related commands and pass them to invoker object
DVDPlayCommand dvdPlayCommand = new DVDPlayCommand();
remote.Invoke(dvdPlayCommand);
DVDStopCommand dvdStopCommand = new DVDStopCommand();
remote.Invoke(dvdStopCommand);
//Instantiate VCR related commands and pass them to invoker object
VCRPlayCommand vcrPlayCommand = new VCRPlayCommand();
remote.Invoke(vcrPlayCommand);
VCRStopCommand vcrStopCommand = new VCRStopCommand();
remote.Invoke(vcrStopCommand);
return 0;
}
}
Step 5:
Compile all above programs as csc /recurse:*.cs
Step 6:
Run the program Client.exe to see the output in your console window
Invoking.......
DVD Started.
Invoking.......
DVD Stopped.
Invoking.......
VCR Started.
Invoking.......
VCR Stopped.
In this example Remote act as an invoker as it invokes DVD or VCR related command request passed to it by the client. Objects beginning with DVD and VCR act as receiver objects and they know how to complete the request. Thus, we can say that Remote(Sender) object does not have any knowledge of the operation, it just invokes the implementation through Execute method. However Receivers know very well how to implement the requested operation (Start or Stop). Hence there is decoupling between Sender(Remote) and Receiver(DVD/VCR).
Usage
One of most common use of this pattern is with Menu Items of a GUI application. Different commands can be created to invoke different functionality by clicking on different menu items of the application.
Disclaimer
The above program is intended solely for learning purpose. Author will not be held responsible for any failure or damage caused due to any other usage.