Command Design Pattern in C#

Command Design Pattern in C# with Examples

In this article, I will discuss the Command Design Pattern in C# with Examples. Please read our previous article discussing the Template Method Design Pattern in C# with Examples. The Command Design Pattern falls under the category of Behavioral Design Pattern. As part of this article, we will discuss the following pointers.

  1. What is the Command Design Pattern?
  2. Real-time Example of Command Design Pattern.
  3. Command Design Pattern Implementation using C#.
  4. Understanding the Class or UML Diagram of Command Design Pattern.
  5. Advantages of Command Design Pattern.
  6. When to use Command Design Pattern in Real-time Application?
What is the Command Design Pattern?

According to the Gang of Four definitions, the Command Design Pattern is used to encapsulate a request as an object (i.e., a command) and pass it to an invoker, wherein the invoker does not know how to serve the request but uses the encapsulated command to perform an action.

The Command Design Pattern is a Behavioral Design pattern that turns a request into a stand-alone object that contains all information about the request. This transformation allows you to parameterize methods with different requests, delay or queue a request’s execution, and support undoable operations. It’s useful in scenarios where you need to issue requests without knowing anything about the operation being requested or the receiver of the request.

Example to Understand Command Design Pattern:

Let us understand the above definition with an example. Please have a look at the following image. As you can see in the below image, the client will create the command object. The command object involves three things. First, the Command Object has the Request (i.e., what to do?). Second, it also has the Receiver Object Reference. The Receiver Object is nothing but the object which will handle the request. Third, the command object also has the Execute method. The Execute method will call the receiver object method, and the receiver object method will handle the request.

What is the Command Design Pattern?

As per the Command Design Pattern, the Command Object will be passed to the Invoker Object. The Invoker Object does not know how to handle the request. What the Invoker will do is it will call the Execute method of the Command Object. The Execute method of the command object will be called the Receiver Object Method. The Receiver Object Method will perform the necessary action to handle the request. For a better understanding, please have a look at the following diagram.

Command Design Pattern in C# with Real-time Example

This is how the command design pattern works. As per the Command Design Pattern, the command object has three things. The first one is the request, i.e., the command. The second one is the Receiver object reference, and the third is the Execute method, which will call the receiver object method to handle the request.

Real-Time Example of Command Design Pattern:

To make you better understand the Command Design Pattern, I have taken the example of a Restaurant. In a Restaurant, the Waiter will be there. What the Waiter will do is, the Waiter will take an order from the Customer. The Customer will tell the Waiter what kind of food he/she wants. The Waiter will note it down on a checklist. Then, the Waiter passes the checklist to the cook. The Cook is the one who will prepare the food and give it back to the Waiter, and the Waiter will give it back to the Customer.

In this example, the Customer is the Client. Order, i.e., what kind of food the customer wants, is the Command. The Waiter is the Invoker. The Waiter does not know how to cook the food. So, the Waiter passes the request to the Receiver, i.e., the Cook, who will prepare the food and give it back to the Waiter, and the Waiter gives it back to the customer.

Command Design Pattern Implementation using C#:

Please have a look at the following image. Here, you can see we have three commands. The first one is the Open Command. It has the request to open the document. Here, the Receiver Object is the Document Object. The Execute Method of the command object will be called the Open Method of the Document Object. Similarly, the Save Command has the request to save a document. Here, the Execute method will call the Save Method of the Document Object. In the same order, the Close Command has the request to close the document. The Execute Method will call the Close Method of the document object.

Command Design Pattern Implementation using C#:

The Invoker Object (i.e., Menu Options) does not know how to handle the requests. So, what the Invoker Object will do is he will call the Execute method of the command object. As you can see, the menus have Open, Save, and Close options.

So, if the user clicks on the Open menu, then it will execute the Execute method of the Open command. The Execute method of the Open Command Object will call the Open method of the Document object (receiver object), which will open the document.

Similarly, suppose the user clicks on the Close menu. In that case, the Invoker Object will execute the Execute method of the Close command, and the Execute Method of the Close Command Object will call the Close method of the Document object to close the document.

In the same way, if the user clicks on the Save menu, the Invoker Object will execute the Execute method of the Save command, and the Execute Method of the Save Command Object will call the Save method of the Document object to save the document. Let us go ahead and implement the above example step by step using the Command Design Pattern in C#.

How to Implement Command Design Pattern in C#?

The Command design pattern encapsulates a request as an object, allowing users to parameterize clients with different requests, queue requests, log the requests, and support undoable operations. It involves separating objects that issue commands from objects that perform the command. Here’s a simple breakdown of the Command Design Pattern:

  1. Command: This is an interface for executing an operation.
  2. ConcreteCommand: This class extends the Command interface, implementing the Execute method by invoking the corresponding operation(s) on the Receiver object.
  3. Receiver: This class knows how to perform the operations associated with carrying out a request. Any class may serve as a Receiver.
  4. Invoker: This class asks the command to carry out the request.
  5. Client: The client creates a ConcreteCommand object and sets its receiver.
Step 1: Creating Receiver Object

Create a class file named Document.cs and copy and paste the following code. Here, we created the receiver class with three methods, i.e., Open, Save, and Close. The Receiver class contains the business logic to perform the actual actions. The following methods will be executed whenever the Invoker calls the Execute Method on the command object. If the Invoker calls the Execute method on the Open Command Object, then the Open Method of the Document Object will be executed. Similarly, if the Invoker calls the Execute method on the Save Command Object, then the Save Method of the Document Object will be executed. And this is the same in the case of the Close Method.

using System;
namespace CommandDesignPattern
{
    // Receiver Object 
    // The Receiver contains the business logic. 
    // They know how to perform all kinds of operations
    // They Know how to handle the Request i.e. Performing the actual Operation
    public class Document
    {
        public void Open()
        {
            Console.WriteLine("Document Opened");
        }

        public void Save()
        {
            Console.WriteLine("Document Saved");
        }

        public void Close()
        {
            Console.WriteLine("Document Closed");
        }
    }
}
Step 2: Creating a Command

First, create an interface named ICommand.cs and copy and paste the following code. We declare one method (i.e., Execute) in this ICommand interface, which executes a command.

namespace CommandDesignPattern
{
    // Command Interface
    // It declares a method for executing a command
    public interface ICommand
    {
        void Execute();
    }
}

We need to create three command classes by implementing the above ICommand interface.

OpenCommand:

Create a class file named OpenCommand.cs, then copy and paste the following code. The following class contains three things. First, it has a reference to the Receiver Object, i.e., the Document object. Second, it has a constructor, which initializes the Receiver Object. Third, it has the Execute method, which calls the Open method of the Receiver Object, i.e., the Document object Open Method.

namespace CommandDesignPattern
{
    // ConcreteCommand A 
    // It defines a binding between a Receiver Object i.e. Document and an Action i.e. Open
    public class OpenCommand : ICommand
    {
        //Reference of Receiver Object
        private Document document;

        //Initializing the Receiver Object using the Constructor
        public OpenCommand(Document doc)
        {
            document = doc;
        }

        //Execute Method will internally call the Receiver Object Open Method
        public void Execute()
        {
            document.Open();
        }
    }
}
SaveCommand:

Create a class file named SaveCommand.cs and copy and paste the following code. The following class also contains three things. First, it has a reference to the Receiver Object, i.e., the Document object. Second, a constructor initializes the Receiver Object, i.e., the document. Third, it has the Execute method, which calls the Save method of the Receiver Object, i.e., the Document object Save Method.

namespace CommandDesignPattern
{
    //ConcreteCommand B 
    //It defines a binding between a Receiver Object i.e. Document and an Action i.e. Save
    class SaveCommand : ICommand
    {
        //Reference of Receiver Object
        private Document document;

        //Initializing the Receiver Object using the Constructor
        public SaveCommand(Document doc)
        {
            document = doc;
        }

        //Execute Method will internally call the Receiver Object Save Method
        public void Execute()
        {
            document.Save();
        }
    }
}
CloseCommand:

Create a class file called CloseCommand.cs and copy and paste the following code. The following class also does the same thing as the previous two classes. It has a reference to the Receiver Object, i.e. Document Object. Second, a constructor initializes the Receiver Object, i.e., the document. It also has the Execute method, which calls the Close method of the Receiver Object, i.e., the Document object Close Method.

namespace CommandDesignPattern
{
    //ConcreteCommand C 
    //It defines a binding between a Receiver Object i.e. Document and an Action i.e. Close
    class CloseCommand : ICommand
    {
        //Reference of Receiver Object
        private Document document;

        //Initializing the Receiver Object using the Constructor
        public CloseCommand(Document doc)
        {
            document = doc;
        }

        //Execute Method will internally call the Receiver Object Close Method
        public void Execute()
        {
            document.Close();
        }
    }
}
Step 3: Creating the Invoker

The Invoker will receive the command but can not handle that request. So, the one and only responsibility of the Invoker is to call the Execute method on the Receiver Object. So, Create a class file named MenuOptions.cs and copy and paste the following code. As you can see, this class contains three ICommand Type variables that are initialized using the constructor. This class also contains three methods, i.e., ClickOpen, ClickSave, and ClickClose, and within these methods, we call the command object Execute method.

namespace CommandDesignPattern
{
    // Invoker  
    // The Invoker is associated with one or several commands. 
    // It sends a request to the command.
    public class MenuOptions
    {
        private ICommand openCommand;
        private ICommand saveCommand;
        private ICommand closeCommand;

        public MenuOptions(ICommand open, ICommand save, ICommand close)
        {
            this.openCommand = open;
            this.saveCommand = save;
            this.closeCommand = close;
        }

        //The Invoker cannot handle the Request, so it internally calls the Execute Method
        //of the Command Object. 
        public void ClickOpen()
        {
            openCommand.Execute();
        }

        //The Invoker cannot handle the Request, so it internally calls the Execute Method
        //of the Command Object. 
        public void ClickSave()
        {
            saveCommand.Execute();
        }

        //The Invoker cannot handle the Request, so it internally calls the Execute Method
        //of the Command Object. 
        public void ClickClose()
        {
            closeCommand.Execute();
        }
    }
}

Note: The Invoker object does not depend on the concrete command or receiver classes. It passes the request to a receiver indirectly by executing a command.

Step 4: Client

The Program class is going to be the Client. So, modify the Main method of the Program class as shown below. Here, you can see. First, we create an instance of the Receiver Object, i.e., Document. Then, we create three command objects by passing the Receiver Object as a parameter, i.e., the Document object. Then, we create an instance of the Invoke, i.e., MenuOptions, bypassing the command objects as parameters. And finally, calling the Invoker methods.

using System;
namespace CommandDesignPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            //Create an Instance of Receiver
            Document document = new Document();

            //Create the Command Object by passing the Receiver Instance
            ICommand openCommand = new OpenCommand(document);
            ICommand saveCommand = new SaveCommand(document);
            ICommand closeCommand = new CloseCommand(document);

            //Create the Invoker instance by passing the command objects
            MenuOptions menu = new MenuOptions(openCommand, saveCommand, closeCommand);

            //Giving command to the Invoker to do the operation
            menu.ClickOpen();
            menu.ClickSave();
            menu.ClickClose();

            Console.ReadKey();
        }
    }
}
Output:

When to use Command Design Pattern in Real-time Application?

Use Cases of Command Design Pattern:
  • When you need parameterized objects with an operation to be executed.
  • When you need to queue operations, schedule their execution or execute them remotely.
  • When you need to implement reversible operations (undo/redo).
Command Design Pattern UML or Class Diagram:

Let us understand the Class Diagram or UML Diagram of the Command Design Pattern and the components involved. Please have a look at the following image.

UML Diagram of Command Design Pattern

As you can see in the above image, the Command Design Pattern consists of five components. They are as follows:

  1. Receiver: This class contains the actual implementation of the method the client wants to call. Our example is the Document class’s Open, Save, and Close method.
  2. Command: This will be an interface specifying the Execute operation. In our example, the ICommand interface has only one method, i.e., Execute.
  3. ConcreteCommand: These classes will implement the ICommand interface and provide implementations for the Execute operation. As part of the Execute method, it will invoke operation(s) on the Receiver object. Our example is the OpenCommand, SaveCommand, and CloseCommand classes.
  4. Invoker: The Invoker will be a class and ask the command to carry out the action. In our example, it is the MenuOptions class.
  5. Client: This is the class that creates and executes the command object. In our example, it is the Main method of the Program class.
Advantages of Command Design Pattern:
  • Separation of Concerns: Decouples the object that invokes the operation from the object that knows how to perform it.
  • Extension: New commands can be added without changing existing code.
  • Composite Commands: You can compose multiple commands into a single command.
  • Undo/Redo Operations: You can keep a history of commands and implement undo or redo functionality.
When to Use Command Design Pattern in C#?

The Command Design Pattern in C# is particularly useful in the following scenarios:

  • Parameterizing Objects with Operations: When you need to parameterize objects with an action to perform, the Command pattern can encapsulate the action as an object, enabling the dynamic assignment and execution of actions.
  • Decoupling the Sender and Receiver: If you want to decouple the object that initiates a request (sender) from the objects that perform the request (receivers). This separation enhances modularity and flexibility in the code.
  • Queueing, Logging, and Undoable Operations: In scenarios where you need to queue operations, log changes, or support undoable operations. Commands can be stored and replayed or reversed as needed, providing significant control over functionality.
  • Implementing Callback Functionality: When implementing callback functionality in applications, where a callback is essentially a command that’s executed at a later point in time.
  • Supporting Undo/Redo in User Interfaces: In GUI applications, where actions performed by the user can be reversed (undo) or reapplied (redo). Each action can be encapsulated as a command that can undo or redo.
  • Transactional Behavior: When implementing transactional behavior, where a series of actions need to be treated as a single atomic operation. The Command pattern can help in implementing such requirements.
  • Extending Applications: In scenarios where an application needs to be extended with new commands without changing the existing code. New command classes can be added to introduce new functionality.

In the next article, I will discuss the Real-Time Examples of the Command Design Patterns in C#. Here, in this article, I try to explain the Command Design Pattern in C# with Examples. I hope you understand the need and use of the Command Design Pattern in C# with Examples.

6 thoughts on “Command Design Pattern in C#”

  1. Good afternoon, hint, the very first example in this pattern with Customer, Order, waiter, cook, it sounds that the customer says what he wants, the waiter sends to the cook and the latter returns the result, but in no place there is not a single example of how to return and most importantly what, in such a bundle, could you add an example of real time, by example of microservices or other options ?

  2. Hello, Thank you for this great article and explanation. Here we can simply perform operations by calling document’s method directly. i.e., document.Open() etc. then why should we use the command pattern as it makes code much complex?

Leave a Reply

Your email address will not be published. Required fields are marked *