Menu
Coddy logo textTech

Command Pattern

Part of the Object Oriented Programming section of Coddy's C# journey — lesson 56 of 70.

The Command pattern is a behavioral pattern that turns a request into a stand-alone object containing all information about the request. This transformation lets you pass requests as method arguments, queue them, log them, or support undoable operations.

The pattern separates the object that invokes an operation from the object that knows how to perform it. It consists of four key components: a command interface, concrete commands, a receiver (the object that does the actual work), and an invoker (the object that triggers commands).

public interface ICommand
{
    void Execute();
}

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

public class TurnOnCommand : ICommand
{
    private Light _light;
    
    public TurnOnCommand(Light light) => _light = light;
    
    public void Execute() => _light.TurnOn();
}

public class TurnOffCommand : ICommand
{
    private Light _light;
    
    public TurnOffCommand(Light light) => _light = light;
    
    public void Execute() => _light.TurnOff();
}

The invoker stores and executes commands without knowing what they do:

public class RemoteControl  // Invoker
{
    private ICommand _command;
    
    public void SetCommand(ICommand command) => _command = command;
    
    public void PressButton() => _command.Execute();
}

// Usage
var light = new Light();
var remote = new RemoteControl();

remote.SetCommand(new TurnOnCommand(light));
remote.PressButton();  // Light is ON

remote.SetCommand(new TurnOffCommand(light));
remote.PressButton();  // Light is OFF

The Command pattern is particularly powerful for implementing undo functionality, macro recording, or queuing operations for later execution. Each command encapsulates everything needed to perform an action, making your system more flexible and extensible.

challenge icon

Challenge

Easy

Let's build a text editor command system using the Command pattern. You'll create a system where editing operations like inserting and deleting text are encapsulated as command objects, allowing the editor to execute them through a unified interface.

You'll organize your code across three files:

  • Command.cs: Define an ICommand interface in the TextEditor namespace with a single method Execute(). Then create two concrete command classes:
    • InsertCommand - takes a Document and a string text in its constructor. When executed, it appends the text to the document and prints Inserted: {text}
    • DeleteCommand - takes a Document and an int count in its constructor. When executed, it removes the last count characters from the document and prints Deleted: {count} characters
  • Document.cs: Create a Document class in the same namespace. This is your receiver - the object that actually performs the text operations. It should have:
    • A private string field to store the content (initialize to empty string)
    • An Append(string text) method that adds text to the content
    • A RemoveLast(int count) method that removes the last count characters (if count exceeds content length, clear all content)
    • A GetContent() method that returns the current content
  • Program.cs: Create an Editor class that acts as the invoker. It should have a SetCommand(ICommand command) method and an ExecuteCommand() method that runs the current command. In your main code, demonstrate the command pattern by processing a series of editing operations.

You will receive the following inputs:

  • Number of commands to execute
  • For each command: the command type (insert or delete) followed by either the text to insert or the number of characters to delete

After executing all commands, print the final document content on a new line with the format Content: {content}.

For example, if the inputs are:

4
insert
Hello
insert
 World
delete
3
insert
!

The output should be:

Inserted: Hello
Inserted:  World
Deleted: 3 characters
Inserted: !
Content: Hello Wo!

Notice how the Editor (invoker) doesn't know anything about text manipulation - it simply executes whatever command it's given. The commands encapsulate both the action and the receiver, making it easy to add new operations like ReplaceCommand without changing the editor!

Cheat sheet

The Command pattern is a behavioral pattern that encapsulates a request as a stand-alone object containing all information about the request. This allows you to pass requests as method arguments, queue them, log them, or support undoable operations.

The pattern has four key components:

  • Command interface - defines the Execute() method
  • Concrete commands - implement the command interface and encapsulate specific actions
  • Receiver - the object that performs the actual work
  • Invoker - the object that triggers commands without knowing their implementation

Command Interface and Concrete Commands

public interface ICommand
{
    void Execute();
}

public class TurnOnCommand : ICommand
{
    private Light _light;
    
    public TurnOnCommand(Light light) => _light = light;
    
    public void Execute() => _light.TurnOn();
}

public class TurnOffCommand : ICommand
{
    private Light _light;
    
    public TurnOffCommand(Light light) => _light = light;
    
    public void Execute() => _light.TurnOff();
}

Receiver

public class Light
{
    public void TurnOn() => Console.WriteLine("Light is ON");
    public void TurnOff() => Console.WriteLine("Light is OFF");
}

Invoker

public class RemoteControl
{
    private ICommand _command;
    
    public void SetCommand(ICommand command) => _command = command;
    
    public void PressButton() => _command.Execute();
}

Usage

var light = new Light();
var remote = new RemoteControl();

remote.SetCommand(new TurnOnCommand(light));
remote.PressButton();  // Light is ON

remote.SetCommand(new TurnOffCommand(light));
remote.PressButton();  // Light is OFF

The Command pattern is useful for implementing undo functionality, macro recording, or queuing operations for later execution. Each command encapsulates everything needed to perform an action, making systems more flexible and extensible.

Try it yourself

using System;
using TextEditor;

// TODO: Create the Editor class (the invoker)
public class Editor
{
    // TODO: Add a private field to store the current command
    private ICommand _command;

    // TODO: Implement SetCommand method
    public void SetCommand(ICommand command)
    {
        // TODO: Store the command
    }

    // TODO: Implement ExecuteCommand method
    public void ExecuteCommand()
    {
        // TODO: Execute the current command
    }
}

class Program
{
    public static void Main(string[] args)
    {
        // Read number of commands
        int n = Convert.ToInt32(Console.ReadLine());

        // Create the document (receiver)
        Document document = new Document();

        // Create the editor (invoker)
        Editor editor = new Editor();

        // TODO: Process each command
        for (int i = 0; i < n; i++)
        {
            string commandType = Console.ReadLine();

            // TODO: Based on commandType, create the appropriate command
            // - If "insert": read the text and create InsertCommand
            // - If "delete": read the count and create DeleteCommand
            // Then set the command on the editor and execute it
        }

        // TODO: Print the final content with format "Content: {content}"
    }
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming