DAO – Real Benefits of a DAO Layer

daodatabase

When I first started using Hibernate I heard about all the joy of using a DAO layer. Initially it made sense for my problem: I was going to experiment with Hibernate and later experiment with NoSQL and/or XML for experience. It made sense at the time

Before I go any farther I want to say that my current DAO layer isn't a "true" dao layer. Its more of a bunch of data objects backed by interfaces and a "Controller" that generates new objects, queries, and cleans up when the application exits.

Now though I'm picking up Spring the DAO layer is starting to make less and less sense. NoSQL is neat and all, but I'm really starting to question if its worth it. I'm not even sure if my data is fit for NoSQL, it works quite well in a relational database. The horrible XML storage seems like a hurdle I'll cross later. Besides there's a huge of code I would need to support for other storage options: My custom "Controller" + a zillion Spring interfaces to implement + other stuff that I'm missing.

What's preventing me though from just ripping it out and merging the core and hibernate dao modules is that there's a few other projects that have a DAO layer (a real one) with only Spring and Hibernate. That means that they have all the interfaces, all the abstract classes, all the complexity with only those two frameworks. Since I'm just starting out in Spring+Hibernate world I'm hesitant to go against what others are doing with so little experience.

Question: Are their other advantages that I'm missing with having a DAO layer? And why would other projects have a DAO layer when their only using one database?

Best Answer

I'll try to tackle part of your question: why do I need a DAO layer if I never intend to swap databases?

As another respondent mentioned part of your goal when writing any class is the Single Responsibility Principle: a class should have only one reason to change. Simply put, you don't want to modify code without necessity, because doing so introduces risk. To minimize that risk, we try and avoid touching the implementation of a class for too many reasons. If I had to alter my class because the business rules changed, or because I decided to change how I mapped it into persistent storage, I would have two reasons to change my code. By removing one of those responsibilities, database mapping, I can avoid the risk of making an mistake that impacts the other, and the testing burden of checking both. I don't want to check my Db mappings, just because I change a business rule. You may also hear people talking about 'separation of concerns', that's another way of expressing this idea. A class that handles my logic for arranging shipping containers should not care about persistence.

It also comes into play when we think about unit testing. When I unit test my shipping container arrangement class, I don't want those tests to be coupled to other concerns, such as persistence. I want to be isolated from them. So I need to be easily able to test in isolation from them. If my class does not contain persistence logic, then I can easily test it in memory, without worrying about how it is persisted.

This driver produces an additional benefit: reasoning about our code. If we don't perform data-access at random points in our code, but through accessing to the DAO through an application service layer and then access to objects returned from that, I will not suddenly have unexpected I/O code running at some point during execution of business logic. It is also much easier to reason about our persistence code if it is not interspersed with business logic.

This makes it much easier to think about our code. We can follow domain logic without having our understanding polluted by access to persistent storage. This ability to reason about code easily is a key to productivity

The ultimate expression of many of these layering ideas is an hexagonal architecture.

You should be aware though that a domain model is not the ideal for all scenarios; particularly where you have no business logic. In that case a transaction script (one thing after another) might be the right solution. Some models, such as CQRS exist to try and gain the benefits of a domain model, without the costs for simple read access, for example for displaying a web page.