Test-Driven Development (TDD) :👈 👉:Observer-Pattern

Command Pattern C#

🧩 Command Pattern - C#

The Command Pattern is a behavioral design pattern that encapsulates a request as an object, thereby allowing you to parameterize clients with different requests, queue or log requests, and support undoable operations.

πŸ”‘ Key Concepts

  • Command: An interface that declares an Execute() method.
  • ConcreteCommand: Implements the Command interface and defines the binding between a receiver and an action.
  • Receiver: The object that performs the actual work when the command is executed.
  • Invoker: Stores and invokes commands.
  • Client: Creates the command and associates it with the receiver.

βš™οΈ Why Use Command Pattern?

  • Decouples the object that invokes the operation (Invoker) from the one that knows how to perform it (Receiver).
  • Makes it easy to add new commands without changing existing code.
  • Supports features like undo/redo, logging, and transactional behavior.

πŸ“– Example in C#

Let’s imagine a simple Remote Control system for a light.

// Command Interface
public interface ICommand
{
    void Execute();
    void Undo();
}

// Receiver
public class Light
{
    public void TurnOn()
    {
        Console.WriteLine("Light is ON");
    }

    public void TurnOff()
    {
        Console.WriteLine("Light is OFF");
    }
}

// Concrete Commands
public class LightOnCommand : ICommand
{
    private Light _light;

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

    public void Execute()
    {
        _light.TurnOn();
    }

    public void Undo()
    {
        _light.TurnOff();
    }
}

public class LightOffCommand : ICommand
{
    private Light _light;

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

    public void Execute()
    {
        _light.TurnOff();
    }

    public void Undo()
    {
        _light.TurnOn();
    }
}

// Invoker
public class RemoteControl
{
    private ICommand _command;

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

    public void PressButton()
    {
        _command.Execute();
    }

    public void PressUndo()
    {
        _command.Undo();
    }
}

// Client
class Program
{
    static void Main(string[] args)
    {
        Light livingRoomLight = new Light();

        ICommand lightOn = new LightOnCommand(livingRoomLight);
        ICommand lightOff = new LightOffCommand(livingRoomLight);

        RemoteControl remote = new RemoteControl();

        // Turn light ON
        remote.SetCommand(lightOn);
        remote.PressButton();

        // Undo (turn light OFF)
        remote.PressUndo();

        // Turn light OFF
        remote.SetCommand(lightOff);
        remote.PressButton();

        // Undo (turn light ON)
        remote.PressUndo();
    }
}

πŸ“ Output

Light is ON
Light is OFF
Light is OFF
Light is ON

πŸš€ Benefits in Real Projects

  • GUI Buttons: Each button can be mapped to a command.
  • Task Queues: Commands can be queued and executed later.
  • Undo/Redo Systems: Each command knows how to reverse its action.
  • Macro Commands: Combine multiple commands into one.
Back to Index
Test-Driven Development (TDD) :👈 👉:Observer-Pattern
*