Saturday, September 05, 2009

 
Did you ever encounter issues while designing systems where more than one component is interacting with other component. If yes, the most obvious issue which you might have encountered would be the coupling issue. That is making one component interact with the other yet not making them know about others functioning. Well, today the pattern we would be talking about revolves around this issue. We are talking about command pattern.

Let us first understand what is command pattern. The formal definition is "Command Pattern encapsulates a request as an object, thereby letting us parametrize clients with different requests, queue or log request."
To understand it better, let us say that we would like to design a scheduler, which reads a request from a queue and process each until the queue is not empty. And possible requests includes:
a) Order request holds data to be written in database if the request is for an order performed.
b) If request pertains to weather reporting tool, it requests a weather class to return current temperature from a data source and then finally writing the data to a remote socket.
c) If request pertains to a third party tool, it reads its DB and creates a connection to a remote server and writes the requested data.

And for performing such operation we already have specific request classes available.
As you can see each of these request is of very different type. And we would not like scheduler to practically verify the request type and then invoke each classes pertaining to the actual request. If we do so, we would be increasing the coupling between scheduler and the request classes.

This seems to be the classic case where we can apply command pattern. Let us jump into this then without wasting any more time.

Well let us see which all classes are available for above requests:

a) Order class which allows setting an Order ID and then making a call to UpdateDB() which updates the DB using the Order ID.

b) For weather reporting a class named WeatherManagement is available, which exposes methods to read data from a component and then finally sending the data to remote client.

c) For third party tool, a class named ThirdPartyToolManagement class is avaiable which allow reading data from DB and then posting the data to an address.

Well, as you have seen we do not want scheduler to directly use these classes, we are going to apply the pattern.

The steps to apply command pattern in our case are as follows:

1. All command object will require to apply a single standard so let us define an interface named Command with a method declared Execute()

2. The actual command needs to implement the interface so that pur scheduler can make call to a single method irrespective of command. The possible commands in our case are
a) OrderCommand

b)WeatherCommand

c)ThirdPartyCommand.

So each of these will require implementing the inteface we defined above.

So let us see one of these classes:

public class OrderCommand implements Command
{
Order objOrder; //this is reference to the class which was supplied for order management

public OrderCommand(Order objOrd)
{
objOrder = objOrd;
}

public void Execute()
{
objOrder.UpdateDB();
}
}

Similarly each of the other commands can be defined.

3. Allowing the scheduler to set the command. For this let us define our Scheduler class, using the one command we have seen for our complete understanding

public class Scheduler
{
Command objCmd;

public void SetCommand(Command objCommand)
{
objCmd = objCommand;
}

public void ExecuteScheduler()
{
objCmd.Execute();
}
}

Let us put this to a trial run:

public class TrailScheduler
{
public static void main(String args[])
{
Schduduler objScheduler = new Scheduler();

Order objOrder = new Order(); //creating an instance of actual receiver

objOrder.SetOrderID(12); //set the order Id on which operation is to take place

OrderCommand objOrdCmd = new OrderCommand(objOrder); //creating a command and wrapping the order instance

objScheduler.SetCommand(objOrdCmd);//setting the command finally in the scheduler

objScheduler.ExecuteScheduler();
}
}

This is explain the functioning, though in reality a Scheduler will be dynamic and will not be static as shown here.

But what we have just seen is a single command. In reality Scheduler will have to deal with multiple command. So the command instance will be an array of commands and scheduler will serially loop though them and execute the command. And in reallity a Scheduler will be a daemon process..so let us dress it up like that



public class Schedueler
{
Command[] aObjCmd;

public void Scheduler()
{
aObjCmd = new Command[10];
Command nullCmd = new nullCommand();

for(int i = 0; i < 10; i++)
{
aObjCmd[i] = nullCmd;
}
}

private void RetrieveNSetCommand()
{
aObjCmd = GetDataFromSource(); //this retrieve the ready command objects from a source
}

public void ExecuteScheduler()
{
while(true) //make it infinite
{
RetrieveNSetCommand(); //this loads all command from a source

for(int i = 0; i < 10; i++)
{
aObjCmd[i].Execute(); //execute each of the retrieved commands
}
}
}
}




Refer to the class diagram below for details.



As you have seen we have decoupled the scheduler from the actual request it is making. Now our scheduler no more worry about the actual command it is processing. All it knows is it is required to make a call to Execute() method and that's all.

If you need any clarification, please write to me.

Labels: , , , , ,


This page is powered by Blogger. Isn't yours?