File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes OO, Patterns, UML and Refactoring and the fly likes Commands refactoring Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Engineering » OO, Patterns, UML and Refactoring
Bookmark "Commands refactoring" Watch "Commands refactoring" New topic
Author

Commands refactoring

Ingudam Manoranjan
Ranch Hand

Joined: Jul 31, 2006
Posts: 48
Background Statement:

I have a common interface which looks like given below:

public interface Command {
void execute(Context ctx) ;
}


I have thousands of Command classes which extend this interface. Most logically the Commands do
the following:

public class MyCommand implements Command{
public void execute(Context ctx)
{
//code for getting objects, values from context
......
.....
//Code for calling service .Invoke EJB etc..
...
...
//Code for doing Post Processing and putting back to Context
..
...

}
}


Problem Statement:

Now I want to extend all the classes so that I can inject some more pre processing and post processing.
Basically I would like the command to have a hook before and after calling the Service. Something like below:

public class MyCommand implements Command{
public void execute(Context ctx)
{
//code for getting objects, values from context
......
.....
CallHookerPreProcessor(this.class);
//Code for calling service .Invoke EJB etc..
CallHookerPostProcessor(this.class);
...
...
//Code for doing Post Processing and putting back to Context
..
...

}
}


Any good solution to the above problem?
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
I'm guessing maybe three goals: 1) Make existing commands continue to run unchanged, 2) Optionally add pre & post processing to existing commands without changing them, and 3) write new Commands to use pre & post. Maybe you only have some subset of those?

Look at the Decorator pattern. That lets you add functionality to an existing object:

Construction is a little tricky because you have to create the Command and the CommandWithHooks. If you're doing a simple Class.forName().newInstance today you'll have to beef up your creator. I don't know if this might run into issues sharing state with the original Command.

Does that seem to go a good direction?


A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
Ingudam Manoranjan
Ranch Hand

Joined: Jul 31, 2006
Posts: 48
Thanks Stan James. I think this solution will work magic for my problem. I can have decorator something like give below.

public class MyCommandDecorator extends AbstractCommandWithHooks{

public MyCommandDecorator()
{
super();
this.command = new MyCommand();
}

protected void preExcuteHook(Context ctx) {
// do preprosesing here..
}
protected void postExecuteHook(Context ctx) {
// do postprosesing here..
}
}

So my object instantiator will treat MyCommandDecorator like any other command. MyCommandDecorator will instantiate the command it is decorating over.

Above achieves the 3 visions you have rightly pointed out.

Thanks again.
Qunfeng Wang
Ranch Hand

Joined: Jan 28, 2005
Posts: 430
Amazing! I've read this pattern, but it doesn't come to my mind when I first see this paste. It's Stan's three goals make me get it.

A question: It seems the preExcuteHook & postExecuteHook works in a same way. Why make them abstract?


To be or not to be. It's a question.
Ingudam Manoranjan
Ranch Hand

Joined: Jul 31, 2006
Posts: 48
preExcuteHook & postExecuteHook will have different implementations for different commands. Hence they are abstract. All my decorator commands need to essentially implement these 2 methods if they want to add any preprocessing and post processing logic.

Ingudam Manoranjan
Ranch Hand

Joined: Jul 31, 2006
Posts: 48
Whilst this solution is great for quite a number of commands, I am still stumbling when I need to injecting preprocessing code JUST BEFORE the Service call and post processing code JUST AFTER the service call.

Wandering how to crack that!
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Commands refactoring