Layering of software is a good think. It helps reducing complexity in great way. Especially strict-layering is interesting, because the upper layer only is able to be dependent to the next lower layer - and there are no circular dependencies. Layers are often realized with packages and interfaces, were interfaces supply the services and the package the namespace. The service implementation is hidden in general.
In the practice there is also a not very convenient fact named "leaky abstractions". It basically says: there is no perfect encapsulation and so perfect layers. Layers also introduce additional complexity or at least some additional infrastructural code. So they are surely not a silver bullet without additional complexity. Actually there should be always a reason to introduce layers, they shouldn't be just another architectural slide...
The DAO-Pattern can be considered as a "Data Service Layer", which encapsulates the particular and often proprietary data access realization.
The main purpose of such a layer would be to make your independent of the particular database or OR-mapper. But even in the past I never replaced the database or even switched from SQL to LDAP.. With EJB3 the JPA provides already an abstraction and encapsulation of the persistence providers.
Not only the database vendor, but even the OR-mapper provider as well, are abstracted. Now the interesting question - is it really suitable to encapsulate the JPA-encapsulation?
In general, before I introduce an additional layer, I ask myself the following questions:
- How often in the past there was a need to replace a certain functionality (e.g. replacing SQL-DB with OODB, flat files, JCA or LDAP)?
- How often already layered (hidden) functionality was replaced, but the layer boundary (e.g the DAO-Interface) had to be changed as well? (and broke so the layers above...)
- How high is the probability, that the realization of an avearage change or feature request will have only a local impact to one layer and not all? (think e.g. about adding new field to an entity. Such a change has impacts to the database, JPA-Entity, probably DAOs, Services, DTOs and mapping logic as well)
- How efficient is the development and maintenance of layers in general (retrospective view)?
There are some cases, like e.g. encapsulation of legacy systems, were layers are mandatory. DAOs in my opinion can be highly optimized in Java EE 5 (until it disappears :-)). The DAO-Interface, implementation and Factory and the actual Session Bean can be collapsed. Of course we could argue, that it isn't very good to be dependent on EJB 3 - but why not? Just because of @Stateless annotation? :-) Btw. annotations are optional, if you love XML, ejb-jar.xml are still there. Using ejb-jar.xml it is very easy migrating POJOs to EJB 3. Dead layers damage not only the architecture, but also makes application unmaintainable and hard to develop. Before the introduction of a new pattern, layer or architectural principle, you should ask yourself: "Do we really needed?". If the answer isn't clear enough, don't introduce it...
[See also Real World Java EE Patterns - Rethinking Best Practices book, Page 80, 137 and 261 for more details]