This week's book giveaway is in the Mac OS forum. We're giving away four copies of a choice of "Take Control of Upgrading to Yosemite" or "Take Control of Automating Your Mac" and have Joe Kissell on-line! See this thread for details.
Hi, I wonder if anyone can help me. I'm trying to refactor some code I've inherited, But I can't quite put my finger on exactly what it is I want to do, and whether there is an elegant solution for it. The code implements an abstract factory to create DAOs.
I have a number of client classes that need to access business objects in different types of repository. Currently the code looks a little like this
CustomerDAO dao = factory.createCustomerDAO(); ...
As you can see, I have different DAO factories for different storage mechanisms. There also one for accessing data through EJBs deployed in an appserver. I currently pass in to the static DAOFactory.getDAOFactory method the type of storage mechanism I want to use (constant values SQL, MEMORY or EJB). In order to change the storage mechanism and therefore the DAOFactory I have to comment in/comment out code - as you can see with the memory DAO in the code snippet above. I would like to control this from a properties file. Although These things are unlikely to change at runtime, it would me much neater and less error-prone if I didn't need to change the code. We use the memory DAOs exclusively for testing (they provide stubbed methods returning hardwired data), negating the need for connections to databases/app servers. Again, it would be extremely useful to be able to switch into "test mode" without rebuilding the code. All reasonably straightforward so far, I could access the properties file inside the getDAOFactory method, instead of passing in a parameter.
The complicating factor is that the the different types of business objects don't all come from the same type of repository (except in the case of the memory one for testing). Customers might come out of the database, whilst details of the services they're subscribed to might come from the app server. What I had envisaged was storing this setup in a properties file something like:
If I do that, rather than pass the property into the getDAOFactory method, it would be neater and more appropriate to retrieve it inside the method. The trouble is it won't know which property to retrieve, as it doesn't know which type of business object is to be accessed until I call factory.createCustomerDAO() or its equivalents. It sort of feels like I shouldn't bother retrieving the factory before using it and that I should just call static methods on it, but that implies that I just need one big ultra mega factory that knows how to do memory, SQL and EJB access. That seems a bit monolithic, so that can't be right.
Can anyone see my confusion? I've seen this article about anonymous abstract factories (http://www.timfanelli.com/index.php?p=26), and that feels a bit more like it could help, but it relies on anonymous class loading, which seems a bit heavy handed and complex. As the title suggests it also feels like there should be some kind factory for returning the right kind of factory - a factory factory? I don't know why, but this just feels like a problem that there should be an elegant solution for.
Now you can map classes to the DAOs that retrieve them in configuration. Combine that with dependency injection - push the configuration into the factory rather than having it read configuration - and you can set up a test case without having the configuration component around:
I have a startup module that reads the configuration and does setSomething like that on a bunch of other modules. It is a frequent site of change and has crazy dependencies all over the project, but there's only one thing like that and I can live with one.
A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi