As a whole the entries are very nice, packed with info and so on. One particular blog entry struck a cord with me and I wanted to discuss it. It is the DAO object entry.
The beginning of that post immediately addresses the actual need for DAOs in an architecture, by referring to another blog post. The conclusion is that "it depends." If your application is complex, you should use DAOs, as they provide a thin layer on top of JPA and its Entity Manager. In this post I argue that encapsulating the EntityManager functionality is not a job for the DAO layer, and that it in fact needs to be rethought, and eventually absorbed by the Service Facade layer.
There are two concerns that are addressed by the DAO pattern. One is actual persistence, and the other is a logical layer within the architecture of the application. As with all design elements there is a downward concern, as well as an upward concern. The downward concern is the persistence. How will we store the data? The upward concern is the way this pattern will fit into our architecture.
I am not going to use the straw man "there are too many layers" argument which dismisses this debate. The job of the layers is to make an application extensible to future business needs, and goes hand in hand with the SOA concept that businesses usually salivate over. So, let us assume either a medium size application or an application that will see rapid growth in functionality in the near future.
I will discuss the downward concern first. DAOs provide an abstraction of the specifics of persistence. DAOs need to map object data to database tables and back to objects. The JPA standard provides a specification for doing exactly this. There are many JPA providers, as indicated by Vincent Partington's blog. At the end of the day, most of these competitors will use JDBC to write some data to a database. They will also need to figure out how to map the data from JDBC results sets to Java objects and back. As you can see the JPA Entity Manager takes care of the downward concern completely.
The upward concern is much more interesting. DAOs offer many advantages to the client programmer. One big benefit is type safety. Another, perhaps bigger benefit is the separation of concerns, i.e. the creation of the "DAO layer." Why even have layers? Partington accurately portrays the flexibility that is gained when a layer is separate within the architecture. Not only can its functionality be changed without affecting the rest of the codebase (he cites logging as an example) but additionally, the functionality contained within can be reused to build out other components which need it, higher in the hierarchy. There are also other, minor benefits such as the conglomeration of all persistence code in one package, and so on. JPA definitely does not address the typesafety concern, and it lacks the cohesiveness to be used as a layer in our hypothetical mid-sized application.
So a DAO-less architecture using JPA seems to be 1 for 2 here. Or is it? Another one of the posts discusses the Service Facade and DTOs. Yet another well thought out entry, it correctly provides the justifications for DTOs (sometimes called Light Beans) and Service Facades. However there is one concern which I want to add, regarding the Service Facade.
One big time sink in real world projects is communication between developers and business analysts. Even intelligent, motivated and hardworking coworkers have a hard time getting the details knocked out when apps are developed. One of the core challenges they face is language. As human beings we cannot help but use overloaded words and phrases that mean something to us, but not quite the same thing to someone else. A UserEntity might mean something to a developer, but it might mean something completely different to a business analyst. The chief virtue of Object Oriented design is our ability to model code on real world problems and their solutions. Therefore it is my claim that service facade objects and their methods must be identified as business objects and verbs by the business analyst first, and then created verbatim by the architect of the application in the Service Facade layer.
Business logic has no place in the persistence layer. Methods called things like "findExecutingChangePlans" should not be present there at all. Unfortuantely, the old DAO pattern, as presented by Partington, does wed those two concerns: the upward and the downward.
The service facade classes implement two interfaces, the proposed IDataAccess<K,V> and also a particular IBusinessInterface. They do this by extending a AbstractBaseDataAccess<K,V> class, which implements all of the "workhorse" methods as proposed by Partington. But they also implement the various "business verbs" created within the IBusinessInterface. Essentially, the DAO pattern no longer exists, while its two functions are still put to work, separated by the advance of technology.
My proposed solution does not eliminate the layers, it merely lets the appropriate components take care of the previously combined functionality: JPA handles persistence (and only persistence) while the Service Facades handle business logic on a more pure level that old-school DAOs. The new solution still brings all of the benefits listed by Partington as part of the DAO pattern:
- No direct dependency on the JPA api from client code.
- Type-safety through the use of generics.
- One logical place to group all entity-specific JPA code.
- One location to add transaction markers, debugging, profiling. This feature is improved, due to the removal of the DAO layer.
- One class to test when testing the database access code.
As well as the benefits listed under the Service Facade pattern:
- Service Facades map DTOs to domain objects and back.
- Service Facades function as the transaction boundary of your application.
- The Service Facade pattern forces you to think about the interface of your application.
The DAO layer does not disappear, its functionality is divided between the Service Facade layer and the JPA provider.