| 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: 407
|
|
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!
|
 |
 |
|
|
subject: Commands refactoring
|
|
|