• Post Reply Bookmark Topic Watch Topic
  • New Topic

designing a Command Processor.  RSS feed

 
Ranch Hand
Posts: 95
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
i m a bit confused.

i m not able to comeup with an idea for creating a cmd processor.

here is my problem definition.
==============================
There is a Command class base for all commands.
There are many subclasses like AddCommand, RemoveCommand, etc.

So, now there is a class CommandProcessor.
it has a method.



i have read somewhere that if one is using such long elseif's than that design is BAD OOP ,and even i have a bad feeling abt this code , so plese guide me to a better design strategy so i can "create new Command objects based on a String argument and execute them".

Also , i u have any different and alternate strategy to accomplish this task, then please point it to me. the Final aim is to create a flexible command processor.
1. which will execute different commands with their arguments, and
2. each command will have its own Class, and
3. for every command request, a new command object MUST be created for handeling that command.

Thanks.
 
Ranch Hand
Posts: 1873
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Jigar,

To avoid if...else you would need Factory/Registry of Commands. That means, that you would have some Map structure where you already load data like,
<cmdName,cmdClass>.

So you can create an interface called Command to model generic command interface (which you seem to already have done) and make AddCommand, DelCommand etc command classes implement it. Then you can essentially load that Map of command names and their executor objects from a configuration file or defined in the constructor whichever is fitting to your application needs.

Now, that Map is contained in a CommandProcessor object which has process(String cmd) method which parses the cmd as you are doing it in current process() method and then do something like,

Command cmd = (Command)map.get(cmdName);
cmd.execute();

Also, if command needs data (which it would I guess otherwise on what input it will operate?), then you might end up modelling data also in generic manner in form of abstract class or an interface. E.g. you can have CommandData as the model and depending upon the Command's nature you can have various implementations of that abstractions.

This design would help you dynamically create command classes and just put their class names in the config file (if you are going the config file way) and then you don't have to worry about how they will get loaded and processed etc...

I hope I am able to write in a way you understand.

Regards
Maulin

[ November 12, 2004: Message edited by: Maulin Vasavada ]
[ November 12, 2004: Message edited by: Maulin Vasavada ]
 
Maulin Vasavada
Ranch Hand
Posts: 1873
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
also...forgot to mention key word... Look for "Command Pattern" on google
 
Jigar Gosar
Ranch Hand
Posts: 95
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
agreed dude but, what will i store in map,???


i need to create new Command object at every request , i cannot store a command object in a map, what if two thread request the same command object???


it would result in disaster, so i cannot store a command object in a map.

i need a way thru which i can cerate a new command object and return it.???


how would i do that???


thanks.
 
(instanceof Sidekick)
Ranch Hand
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Good catch - the singleton objects stored in the map would have to be used with great care. This kind of thing is not uncommon. Servlets work almost exactly like that so it's certainly possible, but if that's not what you want to do ...

You can store the fully qualified classname of every command and make new instances on the fly. I do this in several programs.

Now you get a new instance every time you ask.

If you're in a complex environment, say an EJB container, you may have to fiddle a bit with the classloader. You'll know when you get a class not found exception on a perfectly valid class.

Final point: I like to have an "application assembler" object that reads configuration and "pushes" things like the command map into the command factory. The command factory does not use the configuration module, removing one nasty dependency, and I can configure the command factory on the fly, say for unit tests.
 
Maulin Vasavada
Ranch Hand
Posts: 1873
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Jigar,

I understand your point but I thought your command objects were "stateless". If they are stateful then what you can do is, instead of storing Objects you can just store the Classname (or Classobject) and then create an object something like,

Class cmdClass = (Class)map.get(cmdName); // assuming you are storing Class objects as values

Object tempCmd = cmdClass.newInstance();
Command cmd = null;
if ( tempCmd instanceof Command) {
cmd = (Command)tempCmd;
} else {
// throw exception
}

cmd.execute();

Or if you are using ClassName in the map as value then you would have to use reflection and do similar things as above once you get Class object.

Also, I see why you might have "stateful" object because you would have to pass "some" data to the execute() method BUT you can define execute method to have "DataObject" argument which is again an abstraction to model the data (as I already mentioned in my previous post) and in that case you can avoid having multiple objects created for each cmd request and use Singleton s..

Hope I made sense to you.

Regards
Maulin
 
Jigar Gosar
Ranch Hand
Posts: 95
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
thank you both, Stan James and Maulin Vasavada, u both have been a gr8 help.

but now i m confused ,

whether to store class object in the map , or store FQCN like james suggested.

what are pros and cons , can u guys discuss it here??

it would be a gr8 help.

thanks once againg for both the solutions, it will gr8ly simplify my design.


also Stan James, can u suggest me some book for "unit test design strategies" and your idea of a "application assembler" , i would to love read more about such stuff which will help me write flexible code, which has "virtually zero" dependencies of any kind.
 
Stan James
(instanceof Sidekick)
Ranch Hand
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jigar, scroll on down the forum list to one about OO, UML, Patterns, etc. We chat about this kind of design stuff all the time.

Commands should probably be stateless. I can't think of good reason to keep information from one call to the next. But the other issue is thread safety. I moved some singleton commands from a single-threaded client to a multi-threaded server this year, and their use of member variables introduced some very interesting bugs ... only in integration testing, not in single-user unit testing. Again, singleton threadsafe commands are absolutely possible and as common as servlets, but not the only choice you have. This time it was easier to create new commands than to refactor a bunch of commands and count on the problem never coming up again.

The dependency injector comes from a pattern called inversion of control. I had to read this Martin Fowler article several times to get it because I thought it meant something else entirely ahead of time. That'll hurt your head for sure.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!