Monday, April 8, 2024

Command Design Pattern in C#

The Command Design Pattern is a behavioral design pattern that encapsulates a request as an object, thereby allowing parameterization of clients with queues, requests, and operations. This pattern decouples sender and receiver of a request based on a command, which helps in invoking the right method at the right time without knowing the actual implementation details.

Components of Command Design Pattern

  1. Command: Defines an interface for executing an operation.
  2. Concrete Command: Implements the Command interface and binds a receiver with an action. It defines a binding between the action and the receiver.
  3. Invoker: Requests the command to execute the operation.
  4. Receiver: Knows how to perform the operation.

Example Implementation in C#

Let’s consider a simple example where we have a remote control that can operate various devices like lights, fans, etc. We want to implement the Command Pattern to control these devices.

Create Command Interface (ICommand.cs)
namespace CommandPattern.Command
{
    /// <summary>
    /// Command Interface
    /// </summary>
    public interface ICommand
    {
        void Execute();
    }
}
Create Reciver Class (Light.cs)
namespace CommandPattern.Receiver
{
    /// <summary>
    /// Receiver Class
    /// </summary>
    public class Light
    {
        public void TurnOn()
        {
            Console.WriteLine("Light is on");
        }

        public void TurnOff()
        {
            Console.WriteLine("Light is off");
        }
    }
}
Create Concrete Command Class
TurnOnLightCommand.cs
using CommandPattern.Receiver;
namespace CommandPattern.Command
{
    /// <summary>
    /// Concrete Command
    /// </summary>
    public class TurnOnLightCommand : ICommand
    {
        private readonly Light _light;

        public TurnOnLightCommand(Light light)
        {
            _light = light;
        }

        public void Execute()
        {
            _light.TurnOn();
        }
    }
}
TurnOffLightCommand.cs
using CommandPattern.Receiver;
namespace CommandPattern.Command
{
    /// <summary>
    /// Concrete Command
    /// </summary>
    public class TurnOffLightCommand : ICommand
    {
        private readonly Light _light;

        public TurnOffLightCommand(Light light)
        {
            _light = light;
        }

        public void Execute()
        {
            _light.TurnOff();
        }
    }
}
Create Invoker Class(RemoteControl.cs)
using CommandPattern.Command;
namespace CommandPattern.Invoker
{
    /// <summary>
    /// Invoker Class
    /// </summary>
    public class RemoteControl
    {
        private ICommand _command;

        public void SetCommand(ICommand command)
        {
            _command = command;
        }

        public void PressButton()
        {
            _command.Execute();
        }
    }
}
Client Code(Program.cs)
using CommandPattern.Command;
using CommandPattern.Invoker;
using CommandPattern.Receiver;

Light livingRoomLight = new Light();
ICommand turnOnCommand = new TurnOnLightCommand(livingRoomLight);
ICommand turnOffCommand = new TurnOffLightCommand(livingRoomLight);

RemoteControl remote = new RemoteControl();
remote.SetCommand(turnOnCommand);
remote.PressButton(); // Turns on the light

remote.SetCommand(turnOffCommand);
remote.PressButton(); // Turns off the light
Console.ReadLine();

Output

command design pattern

In this example:

  • Light acts as the receiver of the commands.
  • TurnOnLightCommand and TurnOffLightCommand are concrete commands that implement the ICommand interface.
  • RemoteControl acts as an invoker that can set and execute commands.

The Command Design Pattern helps in making our code more extensible and maintainable by separating the responsibility of issuing a request from the objects that execute the request. It also enables us to create composite commands by grouping multiple commands together.

The full source code is available here:

Happy coding!! 😊

No comments:

Post a Comment

^ Scroll to Top