Question regarding decoupled Factory

Hello Java Experts!

I'm rather new to patterns and I tried to make a Factory of some kind that can return Commands of various types (create, find, update, delete) and of different families (different cases).

The code below works but I would like to hear from you experts what you think of it. Can I go with this design? I specify the Factories and Commands in .properties files.

T.I.A.

/Karl

****************************************************************************************

CLIENT

[...]

CommandFactory cf = CommandFactory.getFactory("casetwo");

Command c = cf.getCommand("update");

System.out.println(c.class.getName());

[...]

Gives the output

[...].command.UpdateCaseTwoCommand

And that's what I want; a command of "update" type from the "casetwo" factory...

****************************************************************************************

public abstract class CommandFactory {

private static Hashtable factories;

Hashtable commands = new Hashtable();

static {

try {

factories = classProperties(CommandFactory.class);//<-- ?

}

catch (Exception ex) {

throw new RuntimeException(ex);

}

}

public CommandFactory(Class c) throws FactoryException {

try {

commands = classProperties(c);

}

catch (Exception ex) {

throw new FactoryException(ex);

}

}

public static CommandFactory getFactory(String factory) throws FactoryException {

return (CommandFactory) factories.get(factory);

}

private static Hashtable classProperties(Class c) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException {

String classname = c.getName();

String prefix = classname.substring(classname.lastIndexOf(".") + 1);

String suffix = "properties";

Properties propsfile = new Properties();

propsfile.load(c.getResourceAsStream(prefix + "." + suffix));

Hashtable properties = new Hashtable();

Map.Entry entry = null;

for (Iterator i = propsfile.entrySet().iterator(); i.hasNext(); ) {

entry = (Map.Entry) i.next();

properties.put( (String) entry.getKey(), ObjectCreator.createObject( (String) entry.getValue()));

}

return properties;

}

public abstract Command getCommand(String action) throws FactoryException;

}

****************************************************************************************

public class CaseOneCommandFactory extends CommandFactory {

public CaseOneCommandFactory() throws FactoryException {

super(CaseOneCommandFactory.class); //<-- ?

}

public Command getCommand(String action) throws FactoryException {

return (Command) commands.get(action);

}

}

****************************************************************************************

And the property file for the factory...

"CommandFactory.properties"

caseone=[...].factory.CaseOneCommandFactory

casetwo=[...].factory.CaseTwoCommandFactory

casethree=[...].factory.CaseThreeCommandFactory

casefour=[...].factory.CaseFourCommandFactory

And one command property file for each factory (four of them)

"CaseOneCommandFactory.properties"

create=[...].command.CreateCaseOneCommand

find=[...].command.FindCaseOneCommand

update=[...].command.UpdateCaseOneCommand

delete=[...].command.DeleteCaseOneCommand

"CaseTwoCommandFactory.properties"

create=[...].command.CreateCaseTwoCommand

find=[...].command.FindCaseTwoCommand

update=[...].command.UpdateCaseTwoCommand

delete=[...].command.DeleteCaseTwoCommand

and so on...

[3818 byte] By [kwiberga] at [2007-10-2 6:46:12]
# 1

this looks way too complex to me.I'll bet I could write it in far fewer lines, and it'd be much more maintainable.

I'd start with the java.lang.Class class as my factory. I'd use its newInstance() methods for creating an object with a default constructor. If I needed a constructor with parameters, I'd use reflection to get it.

The problem with your code is that every time you add a new command or factory you have to change and recompile the source. You'd like to have it be more flexible and dynamic.

It feels like you're making this too hard. Since you're new, and this is your first go at patterns, you also might have "small boy with a pattern" syndrome at work. Be careful! 8)

%

duffymoa at 2007-7-16 13:54:54 > top of Java-index,Other Topics,Patterns & OO Design...
# 2

"create, find, update, delete" - makes me think you're working on a persistence layer.

Command and Factory are not the patterns you want in that case. You want Data Access Object, or DAO.

Your approach is going to result in a lot of fine-grained objects that someone will have to hunt through to figure out all the operations available to persist their model object. A DAO will bring them all into one class where they belong.

If the model object is a Foo, your DAO interface will look like this:

public interface FooDao

{

public Foo findById(Long id);

public List findAll();

public void saveOrUpdate(Foo foo);

public void delete(Foo foo);

}

You can add other find methods if you have other WHERE clauses or indexes.

The nice thing about this design is that now you can have a concrete implementation of a DAO that can change. JDBC? Just an implementation. Hibernate? No problem - new impl.

If you're really worried about making your app configurable with Factories, a better way to do it is inversion of control or dependency injection. The best framework to help you with that is Spring:

http://www.springframework.org

%

duffymoa at 2007-7-16 13:54:54 > top of Java-index,Other Topics,Patterns & OO Design...