Command Pattern

June 23, 2008

Command Pattern

Today’s post will explain what is the command pattern and how to
use it in C#.
You can read my previous posts about design patterns here:
Structural patterns
Decorator pattern 
Proxy pattern
Facade pattern
Adapter pattern
Composite pattern
Bridge pattern
Flyweight pattern

Creational patterns
Singleton pattern
Abstract Factory pattern
Prototype pattern
Factory Method pattern
Builder pattern

Behavioral Patterns
Strategy pattern
Iterator pattern 
Template method pattern

Command Pattern
The command pattern is a very useful pattern.
The main role of the pattern is to encapsulate a request in an
object. By encapsulating the request we gain the following support if
needed:

  • Redo and Undo operations.
  • Requests can be specify, queue and executed when needed.
  • Logging requests can be handled.
  • Composition of transactions inside an object that include the
    transaction atomic operations.

The pattern is used a lot in .Net framework.
System.Data.SqlClient.SqlCommand is an example of the use of command
in ADO.NET. The SqlCommand encapsulate the internal issues of how to
do database operations and give a simple API to execute methods such as
ExecuteScalar, ExecuteNonQuery and etc. Every data access class that
uses the SqlCommand is the command invoker.

Use Cases for the Command Pattern 
You should use the pattern in the following cases:

  • You need support for logging of the changes performed by
    commands.
  • You need redo or undo support.
  • You have commands that different clients can handle in different
    ways.
  • You have a set of atomic operations that you want to include in
    a transaction.

UML Diagram
Command Pattern UML   

Example in C#

    #region Command

 

    interface Command

    {

        void Execute();

    }

 

    #endregion

 

    #region Concrete Command

 

    class ConcreteCommand : Command

    {

        #region Members

 

        private readonly Receiver _receiver;

 

        #endregion

 

        #region Ctor

 

        /// <summary>

        /// Construct a new ConcreteCommand with the

        /// given receiver

        /// </summary>

        /// <param name="receiver">The given receiver</param>

        public ConcreteCommand(Receiver receiver)

        {

            _receiver = receiver;

        }

 

        #endregion

 

        #region Command Members

 

        void Command.Execute()

        {

            _receiver.Action();

        }

 

        #endregion

    }

 

    #endregion

 

    #region Receiver

 

    class Receiver

    {

        public void Action()

        {

            // write whatever action you need

        }

    }

 

    #endregion

 

    #region Invoker

 

    class CommandInvoker

    {

        #region Members

 

        private readonly Command _command;

 

        #endregion

 

        #region Ctor

 

        /// <summary>

        /// Construct a new Command Invoker with

        /// the given command

        /// </summary>

        /// <param name="command">The given command</param>

        public CommandInvoker(Command command)

        {

            _command = command;

        }

 

        #endregion

 

        #region Methods

 

        public void ExecuteCommand()

        {

            _command.Execute();

        }

 

        #endregion

    }

 

    #endregion

The example is very simple. I use a Command interface to hold
the command API that I need. The ConcreteCommand class
implement the interface and holds the receiver of the command
which implement the action of the command. The command itself
is invoked by the CommandInvoker class.

Redo and Undo Code Example
A request for an example of how to make a redo and undo operations
in the pattern was issued in the comment section. The following example
is a very simple example of how to make a redo and undo operations:

    #region Command

 

    interface Command

    {

        void Execute();

        void Undo();

        void Redo();

    }

 

    #endregion

 

    #region Concrete Command

 

    class ConcreteCommand : Command

    {

        #region Members

 

        private readonly Receiver _receiver;

 

        #endregion

 

        #region Ctor

 

        /// <summary>

        /// Construct a new ConcreteCommand with the

        /// given receiver

        /// </summary>

        /// <param name="receiver">The given receiver</param>

        public ConcreteCommand(Receiver receiver)

        {

            _receiver = receiver;

        }

 

        #endregion

 

        #region Command Members

 

        void Command.Execute()

        {

            _receiver.Action();

        }

 

        public void Undo()

        {

            _receiver.UndoAction();

        }

 

        public void Redo()

        {

            _receiver.RedoAction();

        }

 

        #endregion

    }

 

    #endregion

 

    #region Receiver

 

    abstract class Receiver

    {

        #region Methods

 

        public abstract void Action();

        public abstract void UndoAction();

        public abstract void RedoAction();

 

        #endregion

    }

 

    #endregion

 

    #region Concrete Receiver

 

    class ConcreteReceiver : Receiver

    {

        #region Consts

 

        private const int NUMBER_TO_ADD = 1;

 

        #endregion

 

        #region Members

 

        private int _nCurrentState;

        private int _nOldState;

 

        #endregion

 

        #region Methods

 

        public override void Action()

        {

            // save the current state

            _nOldState = _nCurrentState;

 

            // do the action of string concat

            _nCurrentState += NUMBER_TO_ADD;

 

            Console.WriteLine("Current state {0}",

                _nCurrentState);

        }

 

        public override void UndoAction()

        {

            // Return the old state to be the current state

            _nCurrentState = _nOldState;

 

            Console.WriteLine("Undo Current state back to {0}",

                _nCurrentState);

        }

 

        public override void RedoAction()

        {

            // Redo calls the action again to redo

            // the adtion

            Action();

        }

 

        #endregion

The example is based on the code that was showed earlier in
the post. The only difference is that I added the redo and undo
operations and added a ConcreteReceiver that handles the redo and 
undo operations. The example is simple and the undo operation only
saves the last action state. Also, the redo performs the action again
as indicated from a redo operation.

Summary
To sum up the post, I introduced the command pattern.
The pattern is widely used in the .Net framework and is very helpful
once you know how to use it. It can simplify the way you build requests
in the systems that you develop.
The next stop in the tour of behavioral patterns will be the chain
of responsibility pattern.

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

6 comments

  1. Lior IsraelJune 23, 2008 ב 21:17

    you can see also this pattern
    in WPF ICommand(RoutedCommand)
    bool CanExecute(object parameter);
    void Execute(object parameter);

    Reply
  2. Gil FinkJune 24, 2008 ב 8:28

    Thanks Lior.
    As you wrote, WPF’s ICommand is another example for the pattern usage in .Net framework. You can find the pattern in a lot of cases in the framework and not only in System.Data which was an example of usage that I gave in the post.

    Reply
  3. OlegJune 24, 2008 ב 8:51

    Hi Gil,

    It looks useful pattern, but I can’t really understand how to use it in live …
    Could you give concrete example of how to use command pattern – for example for Undo Redo actions.

    Thanks in advance,
    Oleg.

    Reply
  4. Gil FinkJune 24, 2008 ב 13:53

    Hi Oleg,
    I added a section with an example of redo and undo operations. Hope it’ll help to clear things.

    Reply
  5. OlegJune 25, 2008 ב 8:33

    Hi Gil,

    Thanks a lot for an concrete example,
    Just to be sure that I understand. The receiver object representing Concrete object in my system – button for example?

    Reply
  6. Gil FinkJune 25, 2008 ב 9:53

    Hi Oleg,
    The receiver is every object that you want to pass a message to it from the command. It can be database like in the case of SqlCommand, it can be a button in a menu or whatever you need. Hope that it helps.

    Reply