Re: factory objects (idle thoughts)
On Sun, 13 Sep 2009, Stefan Ram wrote:
I read this in the world wide web:
?Having dismissed constructors and static factories, it
seems we need to define a factory class whose instances
will support an interface that includes a method that
constructs the desired objects. How will you create the
factory object? By calling a constructor? Or by defining
a meta-factory? After how many meta-meta-meta- ..
meta-factories do you give up and call a constructor??
http://gbracha.blogspot.com/2007/06/constructors-considered-harmful.html
One answer that came to my mind:
An application may use a constructor /once/ to get its first
object, thereafter it uses only factory methods of this
object and other objects to get all other objects.
(This might have nothing to do with practical Java
programming, I know.)
It reminds me of Amiga programming, where, in 1985,
programmers learned that there is /one/ fixed address, i.e,
the address 4. So an application would go to address 4 to
find the base address of the system library object (it was
not called ?object?, then) and all other objects it would
retrieve directly or indirectly from this object.
You are spot on in identifying this as a bootstrap problem - that it can't
be factories all the way down, there has to be a concrete act of creation
at some point.
However, the solution isn't necessarily a real constructor call. In fact,
i think it can't be - if you construct a concrete root factory, then
you're implicitly fixing the behaviour of the root factory's factory
methods, and so the factory methods of any factories created by those,
etc.
Rather, i think what you want to do is root the construction tree in some
magic that allows the class of the root factory to be chosen at runtime.
This could be something like:
RootFactory rfac;
if (isRunningOnDesktop()) rfac = new GUIRootFactory();
else if (isRunningInBank()) rfac = new FinancialRootFactory();
else rfac = new DefaultRootFactory();
But you might be better off doing:
String rootFactoryClassName = AppConfig.getRootFactoryClassName();
Class<T extends RootFactory> rootFactoryClass = Class.forName(rootFactoryClassName).asSubclass(RootFactory.class);
RootFactory rfac = rootFactoryClass.newInstance();
Where the classname comes from a configuration file, a system property, or
whatever. That lets you control the type of factory as a matter of runtime
configuration, rather than it being hardcoded.
And once you're doing this, you're basically rolling your own dependency
injection framework, and you should probably be using Spring or some such.
tom
--
Intensive Erfrischung