Monday, January 21, 2008

Domain Driven Design in Java: Repositories and DAOs part 3

In the previous posts on the topic (part1 and part2) I've highlighted common characteristics and differences between the DAO and Repository patterns. In situations where the modeled domain is simple, a traditional DAO approach (backed up by frameworks) is probably good enough. If your domain is more complex, or if complexity is growing, differences between DAOs and Repositories become more important.

  • A larger domain calls for a higher level of abstraction: Repositories could help implementing new functionalities because they hide more of the underlying layers.
  • Complex systems cannot always be modeled with a one-database strategy: whether a Model-DAO-DB model makes sense for most of the normal application, this is a "reasonable assumption". There are anyway situation where a Repository should hide more complexity than a simple database call.
  • Simply stating that "access to the database should always happen through Aggregate Roots" could be not enough to preserve your architecture's integrity.

So, given that DAOs come almost for free in a Spring plus Hibernate environment, the question now is understand if we need something more than that. To put in another way, if DAOs drawbacks (tied to the database representation, more data-oriented than model-oriented, not enforcing access only via aggregates but a one-dao-per-entity approach) are something we can live with or a call for a targeted solution. To be honest, there's also one limitation with DAOs, which is related to the layer they belong to (the persistence layer or whatever you want to call it), while it is been said that Repositories belong to the domain layer. This is a controversial issue… I'll leave it for later.

Ok, the proposed approach with Repositories and DAOs is to have Repositories on top of the persistence layer, and have Repositories call specific DAOs. Something like

Which is quite similar to Debasish's proposal on this post. Repositories expose a more business-oriented interface, compared to DAOs and could enforce access only via Aggregate Roots. Repositories should belong to the domain layer, for a couple of reasons:

  • Data access isn't conceptually a dirty thing. A pure OOP approach made up by only traversing associations (and have am ORM framework doing the dirty job behind the scenes) could impact performance.
  • They should not be tied to any implementation issue. Repositories expose abstract store and retrieval operations but no implementation details.
  • They could contain business-oriented logic related to searches: getUnreconciledOperations(BankAccount ba) could be used instead of getOperationByAccountAndDateRange(BankAccount ba, Date from, Date to).

Personally, I like the proposed solution, which is also implemented via Spring dependency Injection. But I can't help feeling somewhat weak when it comes to explain the advantages. I mean "speaking the language of the domain" is a good thing to me. But is quite far to be a compelling principle when it comes to "sell" an architecture proposal to a team. They have established practices with DAOs, and we're suggesting to add another layer on top of it. If you are lucky enough to have a common understanding of DDD principles and values in your team, then you're probably in a sort of positive loop, and one DDD practice enforces another one and the whole result is a good thing. If this is not the case, this approach might look like it provides marginal value at the price of an increased complexity.

One more thing that could get in the way is code-generation. It is often possible to have some sort of code generation applied to DAOs. Such DAOs are good but flat, and in many cases they call for a business-oriented refinement, while hand-coded DAOs are generally somewhere in the middle. But if adding a Repository layer breaks the code-generation cycle, it could (one more time) be not worth the effort.

Friday, January 18, 2008

Domain Driven Design in Java: Repositories and DAOs part 2

In my previous post I've scratched the surface of the Repositores vs DAO debate, showing that there are points in common but also some differences. Now it's time to become a little less technology agnostic and try to solve the problem in a common java environment such as Spring plus Hibernate.

The original specification was totally technology agnostic – the only reference in the DDD book was to entity beans (which sound so na├»ve nowadays) – but there were some recommendations, quoting Eric Evans:

"Before implementing something like a repository, you need to think carefully about the infrastructure you are committed to, specially any architectural frameworks"

Ore the more concise:

"In general, don't fight your frameworks"

Which sounds as pragmatic as one would expect. Ok, we have frameworks. We have Hibernate that provides a convenient abstraction for database access, and we have Spring that suggest a mainstream way to deal with persistence through DAOs and the xxxDAOSupport classes. Do we still need repositories? In many cases the DAO approach could be quite sufficient, even if some attention must be put when dealing with Aggregate Roots.

Accessing persistence only through aggregates

One of the strongest recommendations of DDD is to partition the domain model, to highlight Aggregate Roots and related Entities and Value Objects. As a result you could conceptually draw regions on the class diagram, with some properties:

  • There's only one Aggregate Root per region
  • An Entity can belong to only one region
  • Value objects can be used in different regions

Mapping the concepts to Hibernate, a Value Object can be more or less implemented as a Hibernate Custom Type, while there's no difference in the implementation for simple Entities or Aggregate root. Put in another way, Hibernate's view of the domain model is flatter than the one you can achieve by applying domain driven principles to modeling. Does this matter? It depends a lot on the complexity of the domain. When dealing with relations such as the classic OrderLineItem, applying strictly the "access the data only through the Aggregate Root" rule help solving a lot of complex situations. They're simply less complex. As the system grows, you have a view (I liked the regions on the class diagram) that helps keeping coherence of the system. It's probably overkill for small systems, but DDD is for managing complexity, and it helps. Moreover, this type of approach gives also a consistent way to deal with Hibernate's features like lazy-loading: associations crossing regions boundaries were forced to be lazy-loaded, while inside the regions one could apply eager-loading if needed. So it makes sense to have a centralized access point related to Aggregate Roots instead of generic entities. Still you can enforce this rule by using only one DAO per Aggregate Root, or go for the more radical approach proposed by Debasish Ghosh in his blog, which is to have a Repository Layer on top of DAOs.

Continues on part 3.

Thursday, January 17, 2008

Domain Driven Design in Java: Repositories and DAOs

I past the last days digging the net from some information about the implementation of the Repository pattern, as described in Domain Driven Design, in a typical java environment backed by frameworks like Hibernate and Spring.

It turned out that the situation is more complicated than I expected, and that pieces of information are scattered all around, mostly in newsgroups and blogs, so it took me a while to grasp the whole picture. Here is my summary.

The REPOSITORY specification

The original definition of the repository pattern, comes from Martin Fowler's Patterns of Enterprise Application Architecture, but the pattern itself is credited to Edward Hieatt and Rob Mee. The whole idea is to abstract access to the underlying database and provide the illusion of an in-memory collection of domain objects. Hmmm… sounds a lot like DAO to me. And also a bit like Hibernate's lazy-loading. In fact the two concepts of Repository and DAO, are quite similar: they're doing basically the same thing.

Repositories and DAOs

So the first question is "Are Repository and DAOs the same thing with a different name?". I am tempted to write "Yes!", and this will anyway be a legitimate answer in many cases ( some evidences can be found on the Spring Forum and on Christian Bauer's blog), but some differences in the way the two patterns are used were emerging there and there, so I kept on investigating. Going back to the source didn't help, cause both the original definitions are rather vague, at least in 2008 terms, and open to a wide range of implementation styles. So, even if the original definitions were largely overlapping, common habits in using the two patterns consolidated , making Repositories and DAOs two solution styles for approaching the same problem, with some small differences.

  1. DAOs are strictly tied to the underlying representation on a DBMS. The original specification is more generic, allowing for file-based persistence and the like. But the vast majority of DAOs are pointing to a DBMS. Moreover, commonly used persistence frameworks, such as Hibernate help a lot in managing database portability, so this is a smaller issue nowadays, than it used to be. As a result the DAO concept eventually downsized, to a "database access point" while Repositories are still intended to be generic.
  2. Repositories provide a more abstract view over the underlying data model, providing an interface strictly coherent with the domain. DAOs might be implemented basically in many ways, but frameworks and code generation tools tend to put the focus on the data structure rather than on the domain model. This is sometimes a tiny issue, sometimes just a matter of style, but in large systems can degenerate in a severe maintenance problem.
  3. Repositories enforce access to the persistence layer on a one-repository-per-aggregate basis, while DAOs are normally developed one-per-entity or one-per-table. So, repositories are more tied to the DDD concept of Aggregate Root and have a different granularity than DAOs. This definitely makes the most significant difference.

Somehow, the differences above are just a matter of taste, except for point 3. So objections are valid and discussion may result endless. But for now I'll just say that the two patterns are doing basically the same thing, although with different styles. There are differences, especially if approaching the matter from a DDD angle. What's left to say is if those differences are enough to make a choice between one pattern and another, or eventually to choose both.

For a more complete perspective, please read also part 2 and part 3.

Tuesday, January 15, 2008

Great presentation about Identity 2.0

It's not exactly fresh, 'cause it comes from the OSCON 2005 presentation, but the keynote about Identity 2.0 from Dick Hardt is definitely a good one.