wood burning stoves*
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


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
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!
 
Don't get me started about those stupid light bulbs.
 
subject: Commands refactoring
 
Similar Threads
please answer this 128 questions for WLS. Urgently!
AOP - Getting a local variable from the Caller program
How must be chat app. with protocols ?
Constants and switch statement
Compilation problem!