Reversible Command Pattern


The Reversible Command design pattern encapsulates a request or an operation as an object, thereby allowing you to queue, log, and serialize requests to a store (volatile or durable) and create undo or rollback requests.


With this pattern you basically log all the requests and execute them through a command invoker entity.


Why is this important?


Most transactional resource managers are capable of logging user requests during transaction. When transaction is being committed, commands are executed on the resource. Because the commands had been captured during transaction, it is possible to examine those commands and create undo requests. Inside the rollback process, those undo commands can then be executed.


Where else can I use this?


In scenarios that you need to capture commands and replay those back. You have the ability to serialize the commands (they are simply .NET classes which can be serializable) and replay those at a later date.


Structure


At the heart of this pattern is an interface that defines a command. This interface exposes an Execute method which is called to execute the logged command. It also provides a ReverseCommand property which is a reference to an ICommand, capable of undoing the request.


 


As you can see, it is possible create a concrete command by implementing ICommand.


There is one more required entity here to queue all commands and to execute them. This entity is usually called CommandInvoker and is responsible for the following:


          Keep a list of all commands


          Execute all commands


          Keep track of all successfully executed commands


          Allow the user to revert back all successfully executed commands by executing their reverse commands



Sample Implementation


Here is a sample implementation of this pattern:


ICommand


public interface ICommand


{


  void Execute();


 


  ICommand ReverseCommand


  {


    get;


  }


}


CommandInvoker


public class CommandInvoker


{


 SynchronizedCollection<ICommand> _commands =


   new SynchronizedCollection<ICommand>();


 Queue<ICommand> _executedCommands;


 


 /// <summary>


 /// Call this method to add a new command to the


 /// list of in-memory commands


 /// </summary>


 public void AddCommand(ICommand command)


 {


  // add commands and get them ready for execution


  _commands.Add(command);


 }


 


 /// <summary>


 /// Execute all the in-memory commands


 /// </summary>


 public void Execute()


 {


  // perform a double-check-lock


  if (_commands.Count > 0)


  {


   lock (_commands.SyncRoot)


   {


    if (_commands.Count > 0)


    {


     _executedCommands = new Queue<ICommand>();


     // now execute all the


     // commands one at a time…


     foreach (ICommand command in _commands)


     {


      try


      {


       command.Execute();


       // keep track of all the


       // successfully executed commands


       ICommand rc = command.ReverseCommand;


       if (rc != null)


       {


        _executedCommands.Enqueue(rc);


       }


      }


      catch (Exception ex)


      {


       Debug.WriteLine(


         string.Format(


         “Exception = {0}\r\nCommand = {1}”,


         ex.Message, command.ToString()));


       throw;


      }


     }


    }


   }


  }


 }


 


 /// <summary>


 /// Revert back all the successfully


 /// executed commands


 /// </summary>


 public void RevertExecutions()


 {


  if (_executedCommands != null &&


   _executedCommands.Count > 0)


  {


   lock (_commands.SyncRoot)


   {


    while (_executedCommands.Count > 0)


    {


     _executedCommands.Dequeue().Execute();


    }


   }


  }


 }


}


Concrete Commands


The next step is to build a few concrete commands. For this example I will create 2 simple commands (one reversing the other):


AddUser Command


public class AddUser : ICommand


{


 private IUserManager _receiver;


 public string Username { get; set; }


 


 public AddUser(


  IUserManager receiver, string username)


 {


  _receiver = receiver;


  Username = username;


 }


 


 public void Execute()


 {


  _receiver.AddUser(Username);


 }


 


 public ICommand ReverseCommand


 {


  get


  {


   return new RemoveUser(_receiver, Username);


  }


 }


}


RemoveUser Command


This command will look identical to the AddCommand. Its ReverseCommand property will return an instance of the AddCommand (the reverse of Remove is Add).


As you can see both commands have access to a receiver. This is a reference to an object that the command will be executed on.


Finally,


Everything is in place; I just need to write some code to test it:


// create a user manager


UserManager userManager = new UserManager();


 


// create a command invoker


CommandInvoker invoker = new CommandInvoker();


 


// let’s log a number of requests


invoker.AddCommand(


 new AddUser(userManager, “Pedram”));


 


invoker.AddCommand(


    new AddUser(userManager, “Sara”));


 


invoker.AddCommand(


    new AddUser(userManager, “James”));


 


// display all users before the execution of all commands


Console.WriteLine(“Before execution of commands”);


Console.WriteLine(userManager);


 


// now lets execute all the commands


invoker.Execute();


 


// display all users after the execution of all commands


Console.WriteLine(“After execution of commands”);


Console.WriteLine(userManager);


 


// revert back the commands


invoker.RevertExecutions();


 


// display all users after the revert operation


Console.WriteLine(“After revert execution of commands”);


Console.WriteLine(userManager);


 


Console.ReadLine();


When the above code is executed, you’ll notice that although new commands are created, they are not actually executed until the Execute method on the Command Invoker is called. It is also possible to rollback the changes by calling RevertExecutions:


You can download the samples code from here (It is a Visual Studio 2008 beta 2 solution).

CommandPattern.zip

Comments (3)

  1. ppohmann says:

    Hi Pedram,

    up to now you are the only guy on the web who seems to share my opinion that a command and its reversion should not be in the same class. All other patterns I have seen so far include the Execute and the Revert (or Undo/Redo) within one single class.

    Have you got a reference to the pattern you describe in this post or did you create it by yourself? What is the advantage of this kind of reversibilty over the simple one in your opinion?

    Thanks

    Peter

  2. Nico says:

    Hi Pedram,

    I made a command pattern addition which I called command transaction (http://code-schmoof.com/2009/05/17/command-transactions/). With a transaction you can perform a set of commands, and if you need to cancel the set of commands (e.g. the user presses ESC), you can simply rollback. If you’re interessted, check it out.

    Cheers,

    Nico