Command Pattern (Invoker returns Command) and constructors

hej,

Using the Command Pattern to run DAOs with a bit of business logic so that I can have a different types of Invoker (Command handler) classes depending if transactions are managed a SLSB or a local test client using JTA. Beyond organizing commands there isn't much hassel with using the Command Pattern to hide DAO implementation (i.e. Hibernate) worked in with minor business logic. However, I am wondering if people have run into problems initializing Receiver objects only by overriding Command constructors just to drive different actions within the execute method? (long winded question but view the example below) For example,

interface Commandextends Serializable{publicvoid execute()}

class CommandHandler{public Command executeHandler(Command command)}

class ConcreateCommandimplements Command{

ConcreateCommand(String xvy){this.xvy=xvy}

ConcreateCommand(Long abc){this.abc=abc}

public ReceiverObject getReceiverObject()

....

execute (){

if (xvy!=null){

....do logic...

}

if (abc!=null){

....do other logic....

}

}

}

Question is really when to stop overloading constructors and use setters instead or stear the execute logic externily another way (maybe even breaking the basic idea of the Command Pattern that clients shouldn't know what goes on under the covers)?

thanks / Matthew

[2352 byte] By [young_matthewda] at [2007-10-2 9:55:02]
# 1

you should create more than one implementation of Command

and maybe a CommandFactory :

class LongCommand implements Command {

Long l;

LongCommand(Long l) {

this.l = l;

}

public void execute() {

// do logic

}

}

class StringCommand implements Command {

String s;

LongCommand(String s) {

this.s = s;

}

public void execute() {

// do other logic

}

}

class CommandFactory {

Command createCommand(Object o) {

if (o instanceof String) {

return new StringCommand((String) o);

}

if (o instanceof Long) {

return new LongCommand((Long) o);

}

throw new IllegalArgumentException(o);

}

}

Torajiroua at 2007-7-16 23:59:46 > top of Java-index,Other Topics,Patterns & OO Design...
# 2

or even better than using instanceof, create a configuration file :

java.lang.String=StringCommand

java.lang.Long=LongCommand

add a method to Command :

public void setObject(Object o);

and write your factory like this :

class CommandFactory {

private static final Properties configFile = new Properties();

static {

// load configFile here

}

Command createCommand(Object o) { // throws exceptions, didn't bother declaring them

Class argumentClass = o.getClass();

String argumentClassName = argumentClass.getName();

String commandClassName = configFile.getProperty(argumentClassName);

Class commandClass = Class.forName(commandClassName);

Command command = (Command) commandClass.newInstance();

command.setObject(o);

return command;

}

}

so that the implementation of the factory is stable, all that changes is your config file

hth

Torajiroua at 2007-7-16 23:59:46 > top of Java-index,Other Topics,Patterns & OO Design...
# 3
and of course, l and s should be private attribute members ;-)
Torajiroua at 2007-7-16 23:59:46 > top of Java-index,Other Topics,Patterns & OO Design...
# 4

hej,

Thanks for the reply. Also looking for why overloading isn't a good idea. Rather than doing what Torajirou is suggesting: extend the super interface of Command into catagorical interfaces (i.e. StringCommand and LongCommand).

In short what is the design problem with overloading? Lack of inheritence? Or?

young_matthewda at 2007-7-16 23:59:46 > top of Java-index,Other Topics,Patterns & OO Design...
# 5

it's not overloading but overriding

and trust me, it's the right solution

clients shouldn't be aware of the type of command they get, all they should know is that commands can be executed

polymorphism does the rest

that's (partly) what OO is all about

if you're still not convinced, reread description of the command pattern

Torajiroua at 2007-7-16 23:59:46 > top of Java-index,Other Topics,Patterns & OO Design...
# 6

oh you mean overloading constructors ?

that's not the problem per se

the problem is that you're applying false patterns that bring no benefit to your design

your command's code is spaghetti code cluttered with if-else's and is highly unmaintainable (ever imagined what your execute() method would look like when 100 types of commands exist ? and what's the point in having 99 useless attribute members for each command instance ?)

inheritance and polymorphism helps you get rid of that (if you use the factory I provided), at the cost of (very light) reflection

Torajiroua at 2007-7-16 23:59:46 > top of Java-index,Other Topics,Patterns & OO Design...