🎉 Hooray! After 3 years of work, I've finally released the ebook on design patterns! Check it out »

C#: Command

Command

Command is behavioral design pattern that converts requests or simple operations into objects.

The conversion allows deferred or remote execution of commands, storing command history, etc.

Learn more about Command

Application of the pattern in C#

Complexity:

Popularity:

Usage examples: The Command pattern is pretty common in C# code. Most often it’s used as an alternative for callbacks to parameterizing UI elements with actions. It’s also used for queueing tasks, tracking operations history, etc.

Identification: The Command pattern is recognizable by behavioral methods in an abstract/interface type (sender) which invokes a method in an implementation of a different abstract/interface type (receiver) which has been encapsulated by the command implementation during its creation. Command classes are usually limited to specific actions.

Example: Structure of the Pattern

This example illustrates the structure of the Command design pattern. It focuses on answering these questions:

  • What classes does it consists of?
  • What roles do these classes play?
  • In what way the elements of the pattern are related?

Program.cs: Structural Example

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RefactoringGuru.DesignPatterns.Command.Structural
{
    abstract class Command
    {
        public abstract void Execute();
    }

    class SimpleCommand : Command
    {
        string _payLoad = string.Empty;

        public SimpleCommand(string payLoad)
        {
            _payLoad = payLoad;
        }

        public override void Execute()
        {
            Console.Write($"SimpleCommand: See, I can do simple things like printing ({_payLoad})\n");
        }
    }

    class ComplexCommand : Command
    {
        Receiver receiver;

        string a;

        string b;

        public ComplexCommand(Receiver r, string a, string b)
        {
            receiver = r;
            this.a = a;
            this.b = b;
        }

        public override void Execute()
        {
            Console.Write("ComplexCommand: Complex stuff should be done by a receiver object.\n");
            receiver.doSomething(a);
            receiver.doSomethingElse(b);
        }
    }

    class Receiver
    {
        public void doSomething(string a)
        {
            Console.Write("Receiver: Working on (" + a + ".)\n");
        }

        public void doSomethingElse(string b)
        {
            Console.Write("Receiver: Also working on (" + b + ".)\n");
        }
    }

    class Invoker
    {
        Command onStart;

        Command onFinish;

        public void setOnStart(Command c)
        {
            onStart = c;
        }

        public void setOnFinish(Command c)
        {
            onFinish = c;
        }

        public void doSomethingImportant()
        {
            Console.Write("Invoker: Does anybody want something done before I begin?\n");
            if (onStart is Command)
            {
                onStart.Execute();
            }
            Console.Write("Invoker: ...doing something really important...\n");
            Console.Write("Invoker: Does anybody want something done after I finish?\n");
            if (onFinish is Command)
            {
                onFinish.Execute();
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Invoker invoker = new Invoker();
            invoker.setOnStart(new SimpleCommand("Say Hi!"));
            Receiver r = new Receiver();
            invoker.setOnFinish(new ComplexCommand(r, "Send email", "Save report"));

            invoker.doSomethingImportant();
        }
    }
}

Output.txt: Output

Invoker: Does anybody want something done before I begin?
SimpleCommand: See, I can do simple things like printing (Say Hi!)
Invoker: ...doing something really important...
Invoker: Does anybody want something done after I finish?
ComplexCommand: Complex stuff should be done by a receiver object.
Receiver: Working on (Send email.)
Receiver: Also working on (Save report.)