Design Patterns Simplified: Command - Part 14

I am here to continue the discussion around Design Patterns. Today we will go through one of the behavioral design pattern called Command.

Also in case you have not had a look at our previous articles, go through the following link:

As per GOF guys, Command pattern is defined as in the following.

Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.

Well! Let’s understand what they mean and where this pattern can be fit into.

It means that command pattern wraps the requests into objects and hence provides better control over how to manage various user actions.

This can be used in different Windows based applications (Text Editor, Image Editor andCalculator etc.) where we want better control over user actions or commands. In WPF, DelegateCommand, RelayCommand and RoutedCommands are the example of Command pattern.

It is more suited in cases when we want to implement Undo, Redo, and Copy/Paste kind of operations by storing command or action as an object.

If we were to achieve similar control and flexibility without using command pattern, we need to write lot of repeatedcode in various user actions and maintenance of such code becomes difficult for any future change.

Now let’s see the UML of Command pattern.



Command pattern has five key components as following.

  • Command: This is an interface that holds the generic methods related to actions.

  • Receiver: This class keep the methods for real operations.

  • Concreate Command: This class implements the Command interface and invokes the receiver’s operation.

  • Invoker: Asks command object to execute the action.

  • Client: First creates Concreate Command objects bysetting the receiver then calls the Invoker by setting the concreate command objects.

How Command pattern works?

Invoker calls the Execute methods by passing requests wrapped in command objects. Based on the passed command object, respective concreate command implementation is selected and that in turn invokes the receiver method to do the actual work.

Let's understand this further by simple example.

Let’s begin by creating the Command interface as following.

  1. ///<summary>      
  2. /// The Command interface      
  3. ///</summary>      
  4. public interface ICommand      
  5. {      
  6.     bool CanEexecute      
  7.     {      
  8.         get;      
  9.     }      
  10.     string Name      
  11.     {      
  12.         get;      
  13.     }      
  14.     void Execute();      
  15. }  

 We also need to create Receiver class to have the actual operations.

  1. ///<summary>      
  2. /// The Receiver class      
  3. ///</summary>      
  4. public class Receiver      
  5. {      
  6.     public void AddRecord()      
  7.     {      
  8.         Console.WriteLine("Execute Insert Command");      
  9.         //Call some busines layer or service to make Insert call.      
  10.     }      
  11.     public void UpdateRecord()      
  12.     {      
  13.         Console.WriteLine("Execute Update Command");      
  14.         //Call some busines layer or service to make Update call.      
  15.     }      
  16.     public void DeleteRecord()      
  17.     {      
  18.         Console.WriteLine("Execute Delete Command");      
  19.         //Call some busines layer or service to make Delete call.      
  20.     }      
  21. }    
Now we need to create the concreate command classes by implementing Command interface and having reference to Receiver.
  1. ///<summary>      
  2. /// The ConcreteCommand class      
  3. ///</summary>      
  4. public class InsertCommand: ICommand      
  5. {      
  6.     private Receiver _receiver;      
  7.     public InsertCommand(Receiver receiver)      
  8.     {      
  9.         _receiver = receiver;      
  10.     }      
  11.     public bool CanEexecute      
  12.     {      
  13.         get      
  14.         {      
  15.             return true;      
  16.         }      
  17.     }      
  18.     public string Name      
  19.     {      
  20.         get      
  21.         {      
  22.             return "Insert";      
  23.         }      
  24.     }      
  25.     public void Execute()      
  26.     {      
  27.         _receiver.AddRecord();      
  28.     }      
  29. }      
  30. ///<summary>      
  31. /// The ConcreteCommand class      
  32. ///</summary>      
  33. public class UpdateCommand: ICommand      
  34. {…………………….      
  35.     //Please refer the attached demo project for full source code.      
  36. }      
  37. ///<summary>      
  38. /// The ConcreteCommand class      
  39. ///</summary>      
  40. public class DeleteCommand: ICommand      
  41. {      
  42.     private Receiver _receiver;      
  43.     public DeleteCommand(Receiver receiver)      
  44.     {      
  45.         _receiver = receiver;      
  46.     }      
  47.     public bool CanEexecute      
  48.     {      
  49.         get      
  50.         {      
  51.             returnfalse;      
  52.         }      
  53.     }      
  54.     public string Name      
  55.     {      
  56.         get      
  57.         {      
  58.             return "Delete";      
  59.         }      
  60.     }      
  61.     public void Execute()      
  62.     {      
  63.         _receiver.DeleteRecord();      
  64.     }      
  65. }

Now comes the Invoker that will be called by Client. 

  1. ///<summary>      
  2. /// The Invoker class      
  3. ///</summary>      
  4. public class Invoker      
  5. {      
  6.     public void ExecuteCommand(ICommand cmd)      
  7.     {      
  8.         if (cmd.CanEexecute)      
  9.         {      
  10.             cmd.Execute();      
  11.         }      
  12.         else      
  13.         {      
  14.             Console.WriteLine("You don't have permission to execute {0} command", cmd.Name);      
  15.         }      
  16.     }      
  17. }  
At this stage, we are done with defining Command, Receiver, Concreate Commands and Invoker. Now let’s see how client uses them.
  1. Console.Title = "Command Pattern Demo";      
  2. Receiver rec = newReceiver();      
  3. ICommand insert = newInsertCommand(rec);      
  4. ICommand update = newUpdateCommand(rec);      
  5. ICommand delete = newDeleteCommand(rec);      
  6.       
  7. Invokerinv = newInvoker();      
  8. inv.ExecuteCommand(insert);      
  9. inv.ExecuteCommand(update);      
  10. inv.ExecuteCommand(delete);    
Output



As you can see in the output that Insert and Update commands are getting executed whereas Delete command is not. The reason for Delete command not getting executed is the CanExecute property that is returned as false in DeleteCommand class.

I hope you realized the beauty and power of command pattern by going through the example.

A note to add that please keep your command interface and classes clean by just delegating the request to the receiver and let the receiver do the actual implementation.

You can also download the attached demo project (CommandPatternDemo.zip) to go through the full source code referred in the article.

Hope you have liked the article. I look forward for your comments/suggestions.

Up Next
    Ebook Download
    View all
    Learn
    View all