Thursday, August 28, 2008

Command Pattern as Workflow Pattern

In today's development efforts, we need to ensure that we write better code that really meet our demands, code that can be executed independent of another, code that are separated by what they do (Concerns), a pragmatic code that is very safe to execute (Reliability). An efficient code that handles all error proactively.

To write this kind of code, you need to start dwelling into design patterns or practices that will make life better for all of us. One of this pattern is what i will be discussing today (The Command Pattern). The command pattern as its name implies, is a practice of encapsulating chunks/subsets of operation/workflow into a reusable format that can be used independent of the environment it was called. Command Pattern From Do Factory Website

A typical scenario is this : You are writing a webservices that want to execute the following dependent operations as an atomic operation :

Get details of products/services
Calculate The Payment due.
Make Payment. By calling external webservice (Like payment Gateways).
Update Your Lagacy application.

A good look at the cases above should tell us that these operations will be executed within the CallContext of a method. You can imagine how bulky and spaghetti the underlying code will be, and i can see many if statements, many try catch blocks, many many code horrors. Anyway, let us take another look and approach on the problem on ground, what if we make the processes that we discussed above as a single unit that depends on the statuses of one and other.
As a single Unit we can have the following :


ProductServiceCommand
CalculatePaymentCommand
MakePaymentCommand
UpdateLegacyCommand


The following commands can be written in separate classes, that means that they can stand alone. Before i continue further with this design practices, i will now introduce the Command pattern by introducing the base class below:


abstract public class BaseCommand
{
CommandReciever commandReciever;

public BaseCommand(CommandReciever commandReciever)
{
this.commandReciever = commandReciever;
}

protected CommandReciever CommandReciever
{
get { return commandReciever; }
}

abstract public void Execute();
}


The class above marks the structure/template of our commands, all commands will inherit from this class, and they will override the abstract Execute method. All command will share one instance of a status object or Reciever object (In our context, it is CommandReciever). This object will be used to share information among commands. For example, we may want to check the status of CalculatePaymentCommand before we execute the MakePaymentCommand. If the calculate payment command fails, instead of returning/throwing an exception, we can simply return a status that the other commands can consume. Let us assume that our status is as follows :


public class CommandReciever
{
public CommandStatus ProductStatus{get; set;};
public CommandStatus MakePaymentStatus{get; set;};
public CommandStatus PaymentStatus{get; set;};
public double Amount{get; set;};

public CommandReciever()
{
productStatus = CommandStatus.NOTSET;
makePaymentStatus = CommandStatus.NOTSET;
paymentStatus = CommandStatus.NOTSET;
}
}

public enum CommandStatus : int
{
NOTSET = 0,
OK = 1,
FAILED = 2,
PAYMENT_SUCCESSFUL = 3,
PAYMENT_SERVER_ERROR = 4,
PRODUCT_UPDATED = 5,
UNSUCCESSFUL_PAYMENT = 6,
MAY_CONTINUE = OK,
MUST_DISCONTINUE = FAILED,
}


The commandReciever above will be shared amoung commands, so that state information of other comman can be seen across through the commandReciever object. Now let us delve into implementing our Commands : The following code blocks is the structure of our commands, in our case, i will be describing only one for space and readability on this post:


public delegate void StatusChangedEventHandler(object source, EventArgs e);
public class PaymentCommand : BaseCommand
{

public event StatusChangedEventHandler paymentStatusChanged;

public PendingPaymentCommand
(CommandReciever commandReciever): base(commandReciever)
{

}

public override void Execute()
{
if(commandReciever.ProductStatus.OK)
{
//Execute Payment Command Here.
}
}
}


The class above is a simple template of how the class structure of our commands will be implemented, so let us assume that all other commands inherit from BaseCommand and all commands have a constructor that takes an instance of commandReciever as argument. Also our assumptions is that, they all implement the Execute method.

Now that we are clear about how our four Commands will be implemented, then we will do the calling as follows :


CommandReciever commandReciever = new CommandReciever();
ProductServiceCommand productCommand = new ProductServiceCommand(commandReciever);
CalculatePaymentCommand paymentCommand = new CalculatePaymentCommand(commandReciever);
MakePaymentCommand makePaymentCommand = new MakePaymentCommand(commandReciever);
UpdateLegacyCommand updateLegacyCommand = new UpdateLegacyCommand(commandReciever);


The initialization code above can be used as follows :


productCommand.Execute();
paymentCommand.Execute();
makePaymentCommand.Execute();
updateLegacyCommand.Execute();


At last we have successfully separated each command as workflows that can be executed independently or as a unit of operation. Since commands share statues, a command will check if its other commands have executed successfully before it executes. Commands can also register events on one and other, so we can have some command registering themselves as a listener to a command for status change event notification. There are many usages of the command patterns, this is just one i have explained (Command pattern used as Workflow pattern.( Enjoy patternising).

No comments: