Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / December 2005

Tip: Looking for answers? Try searching our database.

Question regarding decoupled Factory

Thread view: 
Scaramanga - 03 Dec 2005 14:34 GMT
Hello Java Experts!

I'm rather new to designpatterns 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. CanI go with this design? I specify the Factories and
Commands in .properties files.

T.I.A.

/S

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

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...
Chris Smith - 03 Dec 2005 19:48 GMT
> I'm rather new to designpatterns 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. CanI go with this design? I specify the Factories and
> Commands in .properties files.

This is fine, with the following concerns:

1. This is very generic, and could be confusing if the generic API is
not necessary.  For example, if the set of commands is independent of
the "case" and is relatively stable, then if would probably be better
for CommandFactory to have a getUpdateCommand method, instead of relying
on the client to know to pass the String "update" to getCommand.  
Similar concerns might apply to getFactory, but most of the time the
choice you made is justified there.

2. The location of your property files is relative to the package of the
CommandFactory class, if I'm understanding propertly.  It would be
better to place this in a single documented location, and use a global
resource string to retrieve it.

3. Whenever you leave ANY magic character strings in an implementation
as you've done here, be sure to CLEARLY and UBIQUITOUSLY document what
values are appropriate, or how someone go go about discovering that
information.  Nothing is more of a pain than trying to make casual use
of an API and finding out that you need to pass a String that isn't
clearly defined anywhere.

For example, I hate and despise the Java enryption APIs for this reason.  
I think whoever designed them should be fired.  If you don't want people
to feel that way about you, then the javadoc for your API should
include, very clearly in the documentation for each method that takes a
String, exactly what values are guaranteed to work and what they do, and
--if this is a plugin-based API -- how one might find out about
additional values that will be available for some specific
implementation.  Don't let this one slip through the cracks.

Signature

www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation

Scaramanga - 05 Dec 2005 18:46 GMT
>[snip]
>
[quoted text clipped - 20 lines]
> Chris Smith - Lead Software Developer/Technical Trainer
> MindIQ Corporation

Hello Chris,

I couldn't agree more when it comes to documentation! You can be *very*
sure that I will document this one in details if I decide to use it!

And thanks for your other input! My factory is very generic, I know, I
like that kind of design! It's kind of beautiful... But it's not really
necessary in this case because nothing going to change that much. I
don't think I can justify the added complexity to the API.

/S
Roedy Green - 05 Dec 2005 19:26 GMT
>My factory is very generic

There are number of problems with overly generic code. I am talking in
general, not about your factory.

1. they are harder to understand.

2. they often don't actually do any useful work. They just LOOK as if
they were doing something.

3. They are more work to maintain than the straight forward hard code
they replace.

4. they become a sort of job insurance, since the work of making
changes gets dumped on the person who created the abstraction.
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.

Roedy Green - 05 Dec 2005 20:02 GMT
On Mon, 05 Dec 2005 19:26:06 GMT, Roedy Green
<my_email_is_posted_on_my_website@munged.invalid> wrote, quoted or
indirectly quoted someone who said :

>4. they become a sort of job insurance, since the work of making
>changes gets dumped on the person who created the abstraction.

See
http://mindprod.com/jgloss/unmainobfuscation.html#XML

Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.

zero - 04 Dec 2005 00:00 GMT
> Hello Java Experts!
>
[quoted text clipped - 6 lines]
>
> T.I.A.

<snip>

I didn't look at the code extensively, but I did notice that CommandFactory
has a public constructor, but is instantiated through a static factory
method.  Unless you have a good reason to have that constructor public, why
not make it private?

Signature

Beware the False Authority Syndrome

Scaramanga - 05 Dec 2005 07:35 GMT
Thanks for your input!

/S


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.