To Layer, Or Not To Layer, This Is The Question...

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]

Comments:

Adam,

i couldn't resist and posted a blog post in its own at http://gleichmann.blog.com/2054653 (why DAO won't die) for most of your mentioned points. Some of the listet points are recapitulations of my last comments, just for the sake of completeness.

>> 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)?

please have a look at point 6: 'lacks uniform style of representing different data sources'

>> 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...)

please have a look at point 9: 'violation of dependency inversion principle'

>> 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)

Adding a new field to an entity is not primary about data access logic, the main function of a DAO (it should be more about extending the domain modell, thus domain or business driven, but not data driven). But even if you add new fields, business logic may be not involved, since those fields could be only relevant for presentation layer and - data access layer. In addition to that, DAOs interface doesn't have to change by introducing new fields most of time (ok - that's only my experiance :o)).

>> How efficient is the development and maintenance of layers in general (retrospective view)?

good one. Again, its a question of trade off, which i tried to make clear in my post.
If you're not afraid of the mentioned consequences, you're of course free to collapse.
But then i would raise the question, why you'll won't collapse other layers, too ... ;o)

Greetings

Mario

Posted by Mario Gleichmann on September 03, 2007 at 11:32 PM CEST #

DAO is not a layer, it is directly dependant of your business objects and since lower layers can't have dependencies on uppper layers objects, the dao implementations can only be seen as package part of the business layers.

Anyway, I much prefer the Repository (as described in the Domain Driven Design) to the DAO pattern which focus a lot more on the semantic aspect instead of the techical ones and show why the repository abstraction is important. Being able to switch the persistence mechanism used has nothing to do with it if you ask me.

Posted by 83.206.102.99 on September 17, 2007 at 01:23 PM CEST #

Post a Comment:
  • HTML Syntax: NOT allowed
...the last 150 posts
...the last 10 comments
License