loader

Ever been at a restaurant where a friendly waiter takes your order, sends it off to the kitchen, and later delivers your meal exactly as you requested? That’s the Command Pattern in action! It encapsulates a request as an object, letting you parameterize clients with queues, logs, and even undo operations. Think of it like a digital order ticket that holds all the details of what you want, and then hands it off to the chef to execute.

Why Bother with It?

  • Separation of Concerns: Just as a waiter separates your order from the cooking process, the Command Pattern decouples the sender of a request from the receiver that processes it.
  • Flexibility: With orders encapsulated as objects, you can easily queue them up, cancel them, or even store them for later—like a restaurant that manages busy nights by queuing orders efficiently.
  • Undo/Redo Operations: Ever wish you could cancel or modify an order? With command objects, you can implement undo functionality, allowing your system to revert actions if needed.

How It Works (In Plain English)

  1. The Order Ticket (Command Object): You create a command object that represents a specific request—say, “Make a burger with fries.”
  2. The Waiter (Invoker): The invoker takes the order ticket and passes it along to the kitchen. The waiter doesn’t need to know how the burger is made—it just forwards the order.
  3. The Kitchen (Receiver): The receiver is the actual system or object that knows how to process the order. It takes the command and performs the corresponding action (prepares the burger).
  4. Flexible Order Handling: Orders (commands) can be queued, logged, or even canceled—allowing you to manage your restaurant (or application) more effectively.

C# Code Example

C#
using System;

// Command Interface: Represents an order.
public interface IOrder
{
    void Execute();
}

// Receiver: The kitchen that processes orders.
public class Kitchen
{
    public void MakeBurger()
    {
        Console.WriteLine("Kitchen: Burger with fries is ready!");
    }
    
    public void MakeSalad()
    {
        Console.WriteLine("Kitchen: Fresh salad is ready!");
    }
}

// Concrete Command: Order for a burger.
public class BurgerOrder : IOrder
{
    private Kitchen _kitchen;
    
    public BurgerOrder(Kitchen kitchen)
    {
        _kitchen = kitchen;
    }
    
    public void Execute()
    {
        _kitchen.MakeBurger();
    }
}

// Concrete Command: Order for a salad.
public class SaladOrder : IOrder
{
    private Kitchen _kitchen;
    
    public SaladOrder(Kitchen kitchen)
    {
        _kitchen = kitchen;
    }
    
    public void Execute()
    {
        _kitchen.MakeSalad();
    }
}

// Invoker: The waiter who takes and executes orders.
public class Waiter
{
    private IOrder _order;
    
    public void SetOrder(IOrder order)
    {
        _order = order;
    }
    
    public void PlaceOrder()
    {
        if (_order != null)
        {
            _order.Execute();
        }
    }
}

// Client Code
public class Program
{
    public static void Main()
    {
        Kitchen kitchen = new Kitchen();
        
        // Create orders.
        IOrder burgerOrder = new BurgerOrder(kitchen);
        IOrder saladOrder = new SaladOrder(kitchen);
        
        // Waiter takes the burger order.
        Waiter waiter = new Waiter();
        waiter.SetOrder(burgerOrder);
        waiter.PlaceOrder(); // Output: Kitchen: Burger with fries is ready!
        
        // Later, the waiter takes the salad order.
        waiter.SetOrder(saladOrder);
        waiter.PlaceOrder(); // Output: Kitchen: Fresh salad is ready!
    }
}

The Takeaway

The Command Pattern is like handing over a neat, well-organized order ticket to a waiter who then gets your meal from the kitchen. It decouples the request from the execution, giving you the flexibility to queue, log, or cancel orders as needed. Whether you’re building a restaurant management system or a complex software application, using command objects can help keep your code clean, flexible, and easy to extend.

Happy coding—and bon appétit!