Monday, July 28, 2008

Command Pattern


This pattern is a behavioural pattern. Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.
If you look at the Class diagram you see that client set the receiver for ConcreteCommand. Invoker has a list of commands and translates which command should be executed based on condition. (Do not worry about the class diagram we get back to that in a sample). There are different variation for this pattern for example sometimes there are no receiver.
The Command Pattern encapsulates a single function free of any variables. "It elevates the role of a function to the level of a class" Robert C Martin.

When to use this pattern?
When you need to change a method to a class then you can have a group of function in shape of unique class. You can use this pattern to create Undo and Redo functions. You can use this pattern to decouple two behaviours that are highly coupled like validating and doing behaviour. You can use this pattern to route requests, execute actions or forward actions in a uniform way.
In this post I am going to give you a sample of this pattern in real world also in next post I will show you an example of Undo, Redo using Command Pattern.

A real world Sample
I was assigned a task to implement a part of application. In that application users after selecting product and filling different information at final step had to select the payment method which was Credit Card and Ezi pay. The issue was that this application had many users so this part had to be implemented highly scalable and maintainable. I decided to use Command so users request from UI was changed to objects of requests. Because I was dealing with objects I could use message queuing also I could move this part to another server that do this so in that server the invoker did not have any idea about what sort of request are coming. A command was loaded and the execute method was called. I simplified the code and put it in one application to show you how amazing this pattern is. I made the UI very simple (just providing account number) however in real world it is more complex and each of these payments has its own attributes. Also you can check how many commands are in the queue. You can click on submit multiple times then by checking command numbers you see that there are some command in the queue that should be run. I used a queue list however in real world there are better way to implement. Let’s check the code:

UICode:

protected void butSubmitEzipay_Click(object sender, EventArgs e)

{

EziPayCommand cmd = new EziPayCommand(txtAccountNum.Text);

Invoker.Instance.AddCommand(cmd);

}

protected void butSubmitCredit_Click(object sender, EventArgs e)

{

CreditCardCommand cmd = new CreditCardCommand(txtCreditCardNum.Text);

Invoker.Instance.AddCommand(cmd);

}

protected void butCheck_Click(object sender, EventArgs e)

{

lblComandCount.Text = Invoker.Instance.GetNumberofCommandRunning().ToString();

}


As you see for each submit button I am adding the correct command into Invoker object (a singleton object. Just in my case I decide to use Invoker as singleton the pattern do not suggest this however here I needed just one object to control all the request for command by adding commands in a queue and running them one by one)


Invoker Class:

public class Invoker

{

private static Invoker m_Instance;

private bool InProgress=false;

public static Invoker Instance

{

get

{

if (m_Instance == null)

m_Instance = new Invoker();

return Invoker.m_Instance;

}

}

Queue<ICommand> commandList = new Queue<ICommand>();

public void AddCommand(ICommand cmd)

{

lock (this)

{

commandList.Enqueue(cmd);

}

CheckForExecution();

}

//for testing

public int GetNumberofCommandRunning()

{

return commandList.Count;

}

private void CheckForExecution()

{

if (!InProgress && commandList.Count > 0)

{

ThreadStart ts = new ThreadStart(ExecuteCommand);

Thread t = new Thread(ts);

t.Start();

}

}

private void ExecuteCommand()

{

InProgress = true;

while (commandList.Count > 0)

{

lock (this)

{

ICommand cmd = commandList.Dequeue();

}

cmd.Execute();

}

InProgress = false;

}

}


As you see I used singleton pattern here to have just one Invoker object controlling all the command execution. Invoker puts all the requests in a queue and run them one by one. When a command is added to the queue we check wether execution has been started if it is not started by creating new thread we start the process in a separate thread. In the execution process, a command is loaded and it will be run. As you see In Invoker we do not care about type of Command and Invoker itself has no idea which type of command it is running.

Sunday, July 20, 2008

Design Patterns

A Design pattern is a general reusable solution to a commonly occurring problem in software design. Each pattern has an intention that try to solve a common problem. You need to know the intention of each pattern also the problem they solve then if you come up with that issue you need to apply that pattern to solve the problem. I have seen so many programmers have no idea about design pattern if you are part of those people I should say you are not classified as senior programmer. I believe a senior programmer need to know these patterns. I could find a big gap in terms of design patterns knowledge between Java programmers and C# programmers. Java programmers know design patterns very well however; C# programmers hardly know them and use them. I had a lot of co-workers writing horrible codes just because they do not know how to solve a common problem. I wish I had a chance to convince them apart from technologies like ASP.NET, WCF, WF, and etc you need much more deep understanding about coding and design patterns otherwise you may know amazing technology but you do not have enough capacity to use them correctly!

This is why I decided to start writing about design patterns and give you some idea about them and also share my experiences over some of these patterns.

I hope you can find this useful. Please follow my post about design patterns and help me to correct myself also share your experiences with me.