05 Dec 2023



Intermediate

The Command design pattern is a behavioral pattern that turns a request into a standalone object, encapsulating all information about the request. This transformation allows for parameterization of clients with different requests, queuing of requests, and logging of the parameters, as well as providing support for undoable operations. In C#, the Command pattern typically involves the following main components:

  1. Command Interface:

    • Declares an interface with a method (often named Execute) that concrete command classes must implement.
    public interface ICommand
    {
        void Execute();
    }
    
  2. Concrete Command:

    • Implements the ICommand interface.
    • Holds a reference to the receiver and invokes a specific operation on it when Execute is called.
    public class ConcreteCommand : ICommand
    {
        private Receiver receiver;
    
        public ConcreteCommand(Receiver receiver)
        {
            this.receiver = receiver;
        }
    
        public void Execute()
        {
            receiver.Action();
        }
    }
    
  3. Receiver:

    • Knows how to perform the operations associated with a request.
    public class Receiver
    {
        public void Action()
        {
            Console.WriteLine("Receiver's Action method called");
        }
    }
    
  4. Invoker:

    • Asks the command to execute the request.
    • Does not know the specific operation the command will perform, only that it implements the ICommand interface.
    public class Invoker
    {
        private ICommand command;
    
        public void SetCommand(ICommand command)
        {
            this.command = command;
        }
    
        public void ExecuteCommand()
        {
            command.Execute();
        }
    }
    
  5. Client:

    • Creates command objects and associates them with receivers.
    • Sets the command for the invoker and triggers the execution of the command.
    class Client
    {
        static void Main()
        {
            Receiver receiver = new Receiver();
            ICommand command = new ConcreteCommand(receiver);
    
            Invoker invoker = new Invoker();
            invoker.SetCommand(command);
            invoker.ExecuteCommand();
        }
    }
    

In this example:

  • ICommand is the interface that declares the Execute method, which concrete command classes must implement.
  • ConcreteCommand is a concrete implementation of the ICommand interface. It holds a reference to a Receiver and invokes a specific operation on it when Execute is called.
  • Receiver is the class that knows how to perform the operations associated with a request.
  • Invoker is the class that asks the command to execute the request. It does not know the specific operation the command will perform, only that it implements the ICommand interface.
  • The Client creates a receiver, a concrete command, and an invoker. It associates the command with the receiver, sets the command for the invoker, and triggers the execution of the command.

The Command pattern decouples the sender and receiver of a request by turning the request into a self-contained object, allowing for more flexibility and extensibility in the design. It also supports features like undo operations and command queues.

software-design-patterns
command-design-pattern