DAO is a venerable pattern and one that managed to escape out of J2EE and continues to be used a lot in Java development particularly where Spring is also in use. I have never been fan, either the first time around in the Spring and later incarnations. It’s worth having a read through the original blueprint. One thing I particularly love is the proposed combination of Factory and DAO, I find it representative of pattern thinking: if at first you don’t succeed, try excess. In fairness though probably no-one had the problem that the Factory/DAO set out to solve.
I feel the DAO actually creates more problems than it solves. Firstly there is the issue of what the DAO is actually encapsulating. Originally it was meant to encapsulate different data access methods, it would provide the same data retrieval irrespective of whether it was using JDBC, EJB, homebrew ORM or so on. However I do not think I have ever seen it implemented that way, in fact I don’t really recall ever seeing a DAO that had more than one implementation.
What DAO quickly came to be in practice was a replacement for EJBs. The most common implementation maps a single table to a DAO class that implements finder methods that return Collections of a Domain object (if you’re lucky and Lists if not). I think this accounts for 100% of Java DAOs I have encountered in my career. This is exactly what EJB definitions used to be like, arguably the only step forward is that you are now configuring in code. The step back is that you are now implementing all those finders by hand.
So a DAO abstracts something that is irrelevant (data access strategy), is linked directly to the underlying data model (usually the table) and provides an API that is just as useless.
The problem with those finders is that unless the DAO author thought of the query you want to perform then you are out of luck. Without the metaprogamming heavy lifting of a Ruby or Groovy then finders are a dead-end implementation strategy for querying data.
So for me DAOs are an anti-pattern that suck design energy out of the development team in the form of interminable discussions of what particular DAO a finder method belongs to and how many finders should be provided by the DAO. They provide zero decoupling from the underlying data and actually hold development teams back by introducing an unnecessary abstraction layer that needs to be understood but which adds no value.
So what are the alternatives? Well my preferred pattern is DataMapper, this doesn’t introduce unnecessary abstraction and shows a bit of respect for the underlying data. It allows you to do some vertical Domain modelling but the mapping gives you the flexibility to deal with legacy data schemes.
Another good alternative is to ditch the finders and introduce SearchCriteria and Repository. I thought this was a pattern too but it doesn’t seem to have a formal write up, the best example is the Hibernate Criteria but I would urge you to judiciously adapt it to your code rather than just straight up copying the the Hibernate model.
Great Rress, I don’t like DAO too.
I would have to disagree.
Within our development team, we have implemented the DAO Pattern in several different way that does follow the blueprint using Spring. In one case, we had three different Billing Systems that had been acquired via Corporate mergers and buyouts, we had implemented an Adapter pattern with interchangeable DAOs depending on which billing system the customer was associated with; this was put in place until we were able to migrate all customers onto one Billing System. Additionally, we had implemented another system for authentication/authorization which was initially implemented using LDAP/ActiveDirectory; however, due to some of the limitation of Active Directory, we were forced to migrate to a database schema. Because we implemented using the DAO pattern, once the database was developed and implemented, all we had to do was switch up the implementation of the DAO’s which allow for seamless integration without any code modifications to the client calling applications.
Overall, I think the important thing to remember here is that when developing an application, “always code to the interface, not the implementation.” 8^ )
James.
I think you’ve given a great example of the muddied thinking I’m talking about. Three different billing systems are three different services not three different data storage strategies which is what was the point of DAO was originally.
What was significant in your solution was the Adaptor which would have normalised the different APIs. You could then have had three Adaptors and used a Template that was injected with the correct Adaptor for the customer and had the same result.
Ditto the authentication system, the authentication service can have multiple implementations but it is really confused to think that a service system has a DAO, the AD solution didn’t really have a meaningful data component at all.
You seem to be singing the praises of IoC and loosely coupled systems. Well amen to that brother but I don’t believe that DAO is an integral part of that.
Pingback: YouBrew Ext JS starter app - Jacob Heric
In a constant changing world where average age of code reduced to 2-3 years, i find it bit over engineering.