Again there were some interesting debates in the near past, which once again discussed the role of the DAO within enterprise applications, especially based on JEE and EJB 3. One main argument for the dissapearance of DAOs is the very unlikely probability to exchange or replace your once chosen persistence technology, so that you may directly rely on EJBs Entity Manager within your Business Services (since it’s in fact very unlikely that your underlying persistence technology will change). This argument is mostly accompanied with the concern, that the introduction of a DAO Layer might increase complexity and introduce some performance penalties, while direct usage of the Entity Manager let collapse two separate Layers into one.
All in all, those statements raise the impression, that DAOs form a kind of Layer in their own right, or represent at least the main part of your data access Layer.
Let me give you some counter arguments (using some input from ‘J2EE Design and Development’ as well as ‘Domain Driven Design’) which will show you that DAOs aren’t so much about Layers but more importantly about Abstraction and domain specific Encapsulation (that said, with the disappearance of the DAO, collapsing two Layers into one as suggested, there is STILL a data access Layer, you only just jumbled business and data access logic).
Abstraction and Separation of concerns
In this post we mainly look at Abstraction as a ‘result of generalization by reducing the information content of a concept or an observable phenomenon, typically in order to retain only information which is relevant for a particular purpose‘. In case of reasoning about the existence of DAOs , we’re mainly interested in the second part; using Abstraction as a strategy of simplification, wherein concrete details are left, so that a DAOs Client is able to focus on a DAOs effects (the WHAT) he wants to benefit from, rather than worrying about the details (the HOW).
Within this frame, a DAO is mainly useful for decoupling Business Logic and Data Access Logic. The responsibilities between Business Services and DAOS are cleanly separated, so one can easily distinguish the business Logic (e.g. business workflows and rules) from persistence logic / data access logic (e.g. handling specific persistence issues).
From the clients point of view, a DAO hides all the fiddly details of persistence operations, especially if persistence logic is not representable as a one-step-operation but consists of multi-step-operation logic which the client don’t want to mix up with his own tasks.
To make it clear, we are not talking about applications, where the business logic mainly consists of plain data acces operations and not much else. We rather consider separation of existent business logic and data access logic, so a business service can keep focused on the domain model and its domain centric tasks.
A DAO encapsulates data specific logic that may not be intermingled with business logic – there might be various reasons which represent valid conditions (not only esoteric facts, as i saw those settings more than once in former projects):
- providing some kind of complex compensation logic (e.g. logic not expressable by simply marking a Roleback)
- providing some domain related data integrity (e.g. difficult to express as direct constraints within your persistence store)
- transparently handling of normalization issues (the underlying database may was designed for another system or serves in roles other than object store)
- compensating the mismatch between data model and domain model (the relational data design may doesn’t reflect the domain model)
- shielding the client from constraints of a specific persistence technology
All those conditions result in operations you don’t want to embedd next to your business logic.
Under this point of view, you can look at a DAO as a special kind of Strategy pattern, where the implementation of different data access strategies are possible and cleanly hidden from their clients, coming with a very valuable consequence: it leaves us Choice!
Where a DAO is data source agnostic (works with any underlying persistence technology), using the Entity Manager directly within your business Service will lock you into one way of accessing (persistent) objects and one particular O/R Mapping solution.
Plain old (Java) Interface
DAOs (better DAO implementations) usually implement one ore more DAO interfaces. One important (secondary) use case which is often neglected, is the fact that those interfaces are under your control (not so with Entity Manager) and therefore provides the potential for a wide variety of additional (crosscutting) concerns:
- gives you the potential for very different implementations of data access strategies and persistence technologies
- allows for interception strategies (e.g. special, fine grained caching strategies which can be decided on a per-DAo level, time measurement, Filtering, …)
- allows for portable design that isolates any non portable features behind interfaces
- provides a common approach to (multiple) (data) resource management, regardless of the data access strategy
- able to provide a consistent exception hierarchy (not bound to a single exception type hierarchy of one specific technology)
That said, you don’t rely on one specific persistence technology (you may want to thinkk about the costs trying to use a single persistence technology in all use cases), you could even mix O/R with plain SQL or other access strategies on a per-method or per-DAO level due to specific application needs (e.g. improve performance by varying query techniques if needed or leveraging vendor specific features).
Intention revealing interface
By being able to express the offered possibilities and effects of (data) object access through an interface, we’re able to protect clients (Business services) from database oriented models, as said before e.g. by providing transformation strategies to the domain model inside the DAO or Repository (i’m not going into details of the difference between a DAO and a Repository here ).
In this case you’re able to easily provide verbs (not only nouns) in an intention revealing way, expressing the ‘actions’ using a domain centric vocabulary (‘remove all yesterday orders of a customer’).
Under this view, a DAO offers a clear, strongly typed API, which communicates the core concepts and operations of a certain domain (e.g. allow for finder methods with domain arguments, removing the need to maintain object query language Strings in business services). By looking at that interface, it’s immediately obvious which (persistent) objects are retrieved (created, deleted) – the interface communicates the core underlying design decisions about object access (while Entity Manager (with its generic API) allows to apply any persistence operation to any object which makes it hard to find out actually available operations for a specific domain)
Interface segregation Principle
Regarding DAO interfaces, you’re able to obey the Interface Segragation Pronciple: within that frame, DAO interfaces belong to the different Business services which describe their needs by providing a specific DAO Interface they’ll use.
A single DAO implementaion then may implement one ore more DAO Interfaces (hidden from the client eyes) where (again) the Entity Manager only provides a generic API: client’s can’t communicate their needs in a domain oriented way (by providing an accordant interface) in that case.
That said, a specific DAO Interface meets the demand of expressing specific (data) object access needs for a Business service (if seen as a ‘component’ which have to express it’s ‘dependencies’)
As seen, a DAO is not just a Layer for the sake of Layering (replacing that Layer if in need). Instead it provides the potential for clearly separating business logic from data access logic – so the value of a DAO is more related to abstract some irrelevant aspects (in the eye of WHAT, while of course relevant in the eye of HOW ) away from its Clients, resulting in a cleaner separation of concerns.
Again, you always have to consider the given forces and constraints when arguing about the usefulness of DAOs in a specific setting: Of course – like most design decisions – it’s a matter of choosing the one or other side of a trade off. So one is right to say it depends on the context whether to use a DAO or directly include data access logic inside a business service – but you have to be clear about the consequences (which should be aligned with the projects goals which in turn should be also clear). And letting the DAO dissapear or collapsing with your business logic comes with the loss of the mentioned possibilities of Abstraction.