This is part of a series of posts demonstrating software design patterns using C# and .NET. The patterns are taken from the book Design Patterns by the Gang of Four. Here's the series index page.

What Is This Pattern?

The Command design pattern encapsulates a request as an object, thereby allowing us developers to treat that request differently based upon what class receives said command. Further, it enables much more complex architectures, and even enables operations such as undo/redo.

The Chain of Responsibility pattern fits well with the Command pattern, as the former can use objects of the latter to represent its requests.

The Rundown

  • Type: Behavioral
  • Useful? 4/5 (Very)
  • Good For: Encapsulating requests as objects so that they can be processed differently by different receivers.
  • Example Code: On GitHub

The Participants

  • The Command declares an interface for executing an operation.
  • The ConcreteCommand defines a binding between a Receiver and an action.
  • The Client creates a ConcreteCommand object and sets its receiver.
  • The Invoker asks the command to carry out its request.
  • The Receiver knows how to perform the operations associated with carrying out the request.

A Delicious Example

Since just defining the Participants doesn't do a very thorough job of explaining what this pattern is all about, let's build a demo project. In this project, we'll model a system in which we can create an order for a fast food restaurant, and add, remove, and modify items in the order using the Command design pattern.

Several cashiers take orders for a KFC restaurant in Indonesia. Image is KFC Bandung Supermall from Wikimedia, used under license.

To begin building our demo, let's first create a class which represents an item being ordered.

/// <summary>
/// Represents an item being ordered from this restaurant.
/// </summary>
public class MenuItem  
{
    public string Name { get; set; }
    public int Amount { get; set; }
    public double Price { get; set; }

    public MenuItem(string name, int amount, double price)
    {
        Name = name;
        Amount = amount;
        Price = price;
    }

    public void Display()
    {
        Console.WriteLine("\nName: " + Name);
        Console.WriteLine("Amount: " + Amount.ToString());
        Console.WriteLine("Price: $" + Price.ToString());
    }
}

Since those items will be ordered by a patron of the restaurant, let's create a Patron object which will also be our Invoker participant. It just so happens that our implementation of the Invoker also includes a factory method:

/// <summary>
/// The Invoker class
/// </summary>
public class Patron  
{
    private OrderCommand _orderCommand;
    private MenuItem _menuItem;
    private FastFoodOrder _order;

    public Patron()
    {
        _order = new FastFoodOrder();
    }

    public void SetCommand(int commandOption)
    {
        _orderCommand = new CommandFactory().GetCommand(commandOption);
    }

    public void SetMenuItem(MenuItem item)
    {
        _menuItem = item;
    }

    public void ExecuteCommand()
    {
        _order.ExecuteCommand(_orderCommand, _menuItem);
    }

    public void ShowCurrentOrder()
    {
        _order.ShowCurrentItems();
    }
}

public class CommandFactory  
{
    //Factory method
    public OrderCommand GetCommand(int commandOption)
    {
        switch (commandOption)
        {
            case 1:
                return new AddCommand();
            case 2:
                return new ModifyCommand();
            case 3:
                return new RemoveCommand();
            default:
                return new AddCommand();
        }
    }
}

Note that the Patron keeps a reference to an instance of FastFoodOrder, which is our Receiver participant and is implemented like so:

/// <summary>
/// The Receiver
/// </summary>
public class FastFoodOrder  
{
    public List<MenuItem> currentItems { get; set; }
    public FastFoodOrder()
    {
        currentItems = new List<MenuItem>();
    }

    public void ExecuteCommand(OrderCommand command, MenuItem item)
    {
        command.Execute(this.currentItems, item);
    }

    public void ShowCurrentItems()
    {
        foreach(var item in currentItems)
        {
            item.Display();
        }
        Console.WriteLine("-----------------------");
    }
}

FastFoodOrder keeps track of all items in the order, so that when commands arrive at it, it can process those commands using its own list of items.

Speaking of the commands, let's implement the base Command participant:

/// <summary>
/// The Command abstract class
/// </summary>
public abstract class OrderCommand  
{
    public abstract void Execute(List<MenuItem> order, MenuItem newItem);
}

Now we can also implement several ConcreteCommand objects:

/// <summary>
/// A concrete command
/// </summary>
public class AddCommand : OrderCommand  
{
    public override void Execute(List<MenuItem> currentItems, MenuItem newItem)
    {
        currentItems.Add(newItem);
    }
}

/// <summary>
/// A concrete command
/// </summary>
public class RemoveCommand : OrderCommand  
{
    public override void Execute(List<MenuItem> currentItems, MenuItem newItem)
    {
        currentItems.Remove(currentItems.Where(x=>x.Name == newItem.Name).First());
    }
}

/// <summary>
/// A concrete command
/// </summary>
public class ModifyCommand : OrderCommand  
{
    public override void Execute(List<MenuItem> currentItems, MenuItem newItem)
    {
        var item = currentItems.Where(x => x.Name == newItem.Name).First();
        item.Price = newItem.Price;
        item.Amount = newItem.Amount;
    }
}

Now that we've got all the pieces in place, let's create our Client participant which creates a ConcreteCommand and sets the receiver; in this case, let's add several items to our order, then delete an item and change another item.

static void Main(string[] args)  
{
    Patron patron = new Patron();
    patron.SetCommand(1 /*Add*/);
    patron.SetMenuItem(new MenuItem("French Fries", 2, 1.99));
    patron.ExecuteCommand();

    patron.SetCommand(1 /*Add*/);
    patron.SetMenuItem(new MenuItem("Hamburger", 2, 2.59));
    patron.ExecuteCommand();

    patron.SetCommand(1 /*Add*/);
    patron.SetMenuItem(new MenuItem("Drink", 2, 1.19));
    patron.ExecuteCommand();

    patron.ShowCurrentOrder();

    //Remove the french fries
    patron.SetCommand(3 /*Remove*/);
    patron.SetMenuItem(new MenuItem("French Fries", 2, 1.99));
    patron.ExecuteCommand();

    patron.ShowCurrentOrder();

    //Now we want 4 hamburgers rather than 2
    patron.SetCommand(2 /*Edit*/);
    patron.SetMenuItem(new MenuItem("Hamburger", 4, 2.59));
    patron.ExecuteCommand();

    patron.ShowCurrentOrder();

    Console.ReadKey();
}

As the orders are processed by the Receiver (the FastFoodOrder class), the contents of the order changes. Here's the output for this sample project:

A screenshot of the sample project output, showing the changes to the order as commands are submitted.

Will I Ever Use This Pattern?

I have, but you will probably not, unless you are using more complex architectures. In my case, we're building an app using command-query responsibility segregation and event sourcing, two complex architectures which, together, are implementations of the Command design pattern blown up to support large, intricate projects. This is an extremely useful pattern, but invokes a lot of complexity (more so than many other design patterns) so use the Command design pattern with the requisite caution.

Summary

The Command design pattern seeks to encapsulate commands as objects and allow different receivers to process them, according to the receivers' own design.

As always, I like to provide code with my tutorials, so the repository for this pattern is over on GitHub and contains all of the sample code used here.

Happy Coding! And don't eat too much fast food, now, ya hear?

Get My eBook FREE!

Did you enjoy this post? This article and 21 others are also in my free eBook, "The Daily Design Pattern", which you can get just by signing up for my email list.