why DAO won’t die

there were some statements and blog posts about the end of the DAO pattern in the last weeks, especially in conjunction with the rising of EJB 3 and it’s EntityManager. those proposals suggest to use EntityManager directly inside your business oriented services instead of encapsulating data access logic through a DAO.

i strongly disagree with this opinion. Here are some of my thoughts, why DAOs will live on:

mixing business logic with data access logic

you are tangling data access logic with business logic, especially when you have to build not only simple queries (not talking about the simple CRUD operations) but introduce i.e. more complex query building logic next to your business logik.

violation of single responsibility principle

mixing business logic and data access logic in one place gives you at least two differents reasons / causes to change.
on the one side, you may have to adapt the core business logic due to new requirements. on the other side data access logic may also change (maybe joining another table for an aggregation because of changes in the data model)

reduced readability

when you mix business logic with more complex data access logic, readability of your business services core purpose is hindered.
EntityManager provides a fixed, generic API, agnostic to your current domain context. everything within data access logic that goes beyond simple CRUD- operations has to be implemented within the service. but i only want to ‘see’ my core business logic in first place, not worrying about the data access logic – you should only see the WHAT, not the HOW of that data access logic. the HOW should be hidden behind a reasonable, intention revealing interface for the sake of comprehensibility.

mixing business logic and infrastructure

you are binding your business services to a special technology. i rather wouldn’t mix business logic with infrastructure / technology, even if the chance is very small that technology changes, but keeping business logic free of any infrastructure (ok, this seems to be a little bit dogmatic, but binding to a special technology fixes your business logic in a very hard way, especially if you want to reuse your business logic within another technical infrastruture).

harder to test

creating mocks for EntityManager is potentially harder, since you may pass complete queries (EJB QL expressions). your mock have to inspect those query statements on a semantic level in order to behave correctly, which may be not so trivial.

lacks uniform style of representing different data sources

in a system where you have to access not only one type of data source (i.e. a relational database, an ldap database, legacy integration via message queues, …) you’ll know have different styles / levels of integration. those access logic isn’t hidden behind an abstract interface any longer. but the client of those data sources shouldn’t worry about the kind of data source. this should be encapsulated.
(in this case it’s not the question, that it’s extremely rare to replace one kind of data source with another one, but having most of times different types of data sources in parallel)

lacks uniform style of data access strategies

using EntityManager directly bounds you to the offered possibilities of its API. should you like to use JDBC in special cases or an alternative qriteria API, you’ll end up with different data access technologies within your service.

violation of open closed principle

your business service is not open for extensions due to data access logic without changes, because it depends directly to the technical API. for example you can’t exchange an existing data access / query building strategy (i.e. building a query string dynamically vs. using a query API) – you have to modify the business service itself, since you don’t hold control of the EntityManager’s implementation.

violation of dependency inversion principle

your higher level component (your business service) is directly dependend on a lower level component (EntityManager)
even if EntityManager is an interface, since you don’t hold control of it’s implementation (not now, not in the future), you are directly bound to it’s API and it’s implementation. should the interface of EntityManager change – the service has to change, too.
(if using dependency inversion principle the right way, it’s not relevant if the underlying DAO interface will change, because THERE IS NO DAO interface in its own right. there is no DAO interface in its own right since the clients define there data access needs, means that there may be many DAO interfaces which belong to the different clients and not to the DAO implementation. this goes along with the interface segregation principle – see Agile Software Development by ‘Uncle Bob’ Robert C. Martin)

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 ‘killing’ the DAO comes with the mentioned ones.

Advertisements

23 Responses to “why DAO won’t die”

  1. Arnon Rotem-Gal-Oz Says:

    What you say is true if the alternative to DAO is to embed data access logic in the domain model. However an alternative that uses a data access layer which translates entities to persistence without using Data Transfer Objects is a valid alternative (IMHO)

  2. Anonymous Says:

    i agree with you about all of it, but there is always one thing i didnt understand about DAO, why we should use interface with DAO? for me really complicates development, because first i write method in DAOImpl class and then i have to add it to interface. I never saw two implementation of DAO interface(in test you can subclass). Isnt it just about being cool and using extra interfaces?(i know that some people to feel sexy use interface for every class) because you can always subclass the main DAO class and throw exception for not implemented method, so i heard because i never done it. you might say its alot of work and you might forget some methods, but for me that never happens,but i always need to extract method to interface.

  3. opensourcereader Says:

    Anonymous just for you information, I current work for a projet where we have 3 DAO implementations
    –> hibernate
    –> xml rpc (platform X)
    –> soap (platform Y)
    In such case you use an interface of course … By anyway programming against interface is the way to go … unless it is a pain, as does not give you anything 🙂
    If you will only use 1 dao, well … just skip the interface part, you’ll be happy too 😀

  4. WarpedJavaGuy Says:

    DAO’s will not die any time soon. Persistence and data access are not one and the same. How you use the two depends on your application architecture. If you are using a layered architecture for your application then your business model should be isolated from technology and loosely coupled to other layers. From a data access perspective this means isolation from JDBC, EJB, Hibernate, JDO, and the like. It’s all about having transparent data access. DAO’s provide this isolation and transparency through interfaces, regardless of the type of data, storage mechanism, and access API.

    Persistence frameworks and API’s would have to provide very flexible data access through very indirect means for there to be no need for DAO’s.

    • Doc Says:

      Thank you a tremendous post, would read your particular others content. thanks for your thoughts for this, I felt a lttle bit strike by this article. Thanks again! You wanna make a great aspect. Has fantastic report here. I feel if a greater number of people coitoderasnin for it that way, they’d have a better time have the hold ofing the issue.

  5. Anonymous Says:

    fully agree with the article, JPA is a cool persistence technology but nothing more than that

  6. Anonymous Says:

    Thanks for finally giving me an example of different datasources.
    Do all those datasource-provider-classes implement the same interface? Like..

    “public Object getFancyObject(Long id);” ?

    And you have ORM/soap/xml rpc implementations for different platforms/use-cases?
    Thank you for expanding my horizon on this. I never thought about structuring an application with those kind of datasources in mind. But then again, I have in previous projects not been confronted with those kind of reqs.

  7. opensourcereader Says:

    Yes all my database-provider-classes implement the same interface.
    However in such case a “public Object get(Pk)” does not means anything when you are using different datasources.
    The only way to go is get(Object), and the DAO implementation will be responsible for the right strategy to retreive the object.
    For instance the hibernate dao does get(object.getPrimaryKey) and my soap does remote.get(object.getRemotePrimaryKeyStoredInMyLocalDB)

    Enjoy your day

  8. koodud Says:

    Well
    DAO as Interface implementation is used to make the code more portable.
    Its easier to invoke code via just getting a handle than actaully creating an object.
    Plus interface really lay a strong foundation for creating N-tier system.

    So its more of a practical approach.

    For example tale a ClentServer App.
    If we use your methodology of not creating interface then we have to port the implementation class to client side too.
    Where as not in the interface implementation case and also effect of further changes to implementation
    would only reflect on server side.

  9. Antonio Goncalves Says:

    I agree with what you say. On the other hand, Java EE has suffered of so much boiler plate code, design patterns that turned into anti-patterns, complexity and so on, that I have no problem in using EntitManager CRUD operations on my EJBs. For simple application, I skip the DAO pattern, otherwise, I keep on using it for the reasons you’ve mentioned.

  10. Mario Gleichmann Says:

    Arnon,

    i’m not quite sure what you mean by embedding data access logic within the domain model. Do you suggest to include basic persistence operations like ‘store’ or ‘load’ into your business objects? Personally, i wouldn’t recommend to make your business objects aware of an non-business issue like persistence or even bound them to a certain persistence strategy. I would rather keep my business objects clean of any infrastructure issue. That said in this point of view, persistence looks more like an crosscutting concern to me, that i wouldn’t mix with business logic.

    To your second statement – again i’m not sure if i understand you right: DAOs are NOT related to Data Transfer Objects. Far from it. Personally, i rather would go with a rich domain model, including behaviour rich business objects instead of anemic, ‘dumb data continers’. Even in the scenario of a rich domain model, DAOs make sense, since you are still in need of encapsulating access logic in an intention revealing way, supporting the mentioned principles.

    Regards

    Mario

  11. Mario Gleichmann Says:

    Anonymous,

    there are three main reasons using interfaces in conjunction with DAOs (or any other services) that comes to mind ad hoc:

    1. Testing
    Imagine you have a business service, that uses a DAO in order to retrieve some business objects in order to get its job done. If you want to test this service (‘the job’ it performs) in isolation (without using the real DAO implementation which you don’t want to test in this case), you have to ‘disconnent’ the DAO implementation from the service you want to test and provide a Mock or Dummy implementation that will behave accordingly to your test scenario in this case.
    If the service would directly depend on the DAOs implementation class, it would be impossible to replace it by a Mock. If the service only depend on the interface you can simply replace the underlying implementation, as long as the Mock or Dummy implements the same interface. It’s completely transparent for your service under test, giving you full control of the behaviour over all dependend DAOs. This comes normally along with a grasp pattern called dependency injection, making your service independent of the implementation it will work with (where the dependend DAOs will be injected via constructor or setter injection in most of cases – you may have a look at some solutions that support dependency injection like Spring or pico container).

    2. Proxying / Interception
    Having decoupled the service from the concrete DAO implementation, it’s fairly easy to proxy the DAO.
    Imagine you want to measure the time for a specific DAO method. Where you’ll put your measuring logic? Inside the service? Inside the DAO? To be at least invasive as possible you could put those logic in a class of it’s own, which wraps the original DAO implementation and implements the DAO interface, too. Now you inject the time measuring DAO wrapper to your service (remembering dependency injection?). Your service is happy, as long as the given / injected objects implements the DAO interface. Now if the service calls the implied DAO method, it first invoke the DAO wrapper which will start the stopwatch, delegating the call to the real DAO implementation afterwards. When the call returns the Wrapper will halt the stoppwatch an calculate the required time. You’ve done this without ‘polluting’ your core implementations – whether the DAO nor the service have to worry about time measurement. Pushing such an Interceptor / Proxy between the client (the service) and the server (the DAO) wouldn’t be impossible without an interface (as long as you don’t use instrumentation of the class files). Measurement was a very simple example, you could use this structure for many more purposes (caching, remote calls of the DAO, …)

    3. Replacement
    You can easily replace one DAO implementation without another one. Admitted, this might occur only in rare cases. But it’s fairly simple to change your favorite data access strategy for example or change the DAOs implementation without affecting the service. You could for example consolidate to different DAO implementations that belong to the same domain context (or split them again should it turn out, that the DAO now share more than one responsibility). Your service is completely agnostic against those implementation ‘details’, since its only depend to a (stable) interface of its needed data access operations.

    Regards,

    Mario

  12. Mario Gleichmann Says:

    Antonio,

    well spoken! DAO usage isn’t a dogmatic rule. You have to trade off the pros and cons of using DAO as an additional abstraction or not (apropos abstraction: by encapsulating data access logic, you’ll get the chance to handle those boiler plate code in a general way. Springs xxxTemplates for example had shown that proof).
    In the original post i tried to make clear what consequences might follow should you decide not to use DAOs. If those consequences are not contrary to your projects goals, nothing argues against skipping DAO.
    In my opinion, most of the more serious projects will state such goals and demand for ‘ilities’ that will stay in pure contrast to those consequences.

    Regards

    Mario

  13. Anonymous Says:

    I don’t see why an application needs to be partitioned more than it needs. For example, you have a client layer… call it a web layer if you want. It knows how to interact with the user. It doesn’t know how you’re storing your data or how the business rules work.

    Next would be your domain layer. This includes your business objects (Person, Address, etc) and your service layer with which the above client layer communicates to get the business rules and business objects working.

    Why does this service/domain layer need to then talk to a “DAO layer” to talk to the database when the application is already using Hibernate? The methods in the server/domain layer are already wrapped in a transaction so they already know about the underlying mechanism so why not just include the Hibernate calls in where the business service is already?

    As far as testing is concerned, using Spring’s AbstractAnnotationAwareTransactionalTests (or its parent class AbstractTransactionalDataSourceSpringContextTests) and the executeSqlScript method, you can prepare the database exactly as needed for the JUnit test to pass. Maybe it’s not pure unit testing form to use a database instead of stubs or mock objects but it works great for me (and obviously others as the method wouldn’t exist).

    Vega

  14. Mario Gleichmann Says:

    Vega,

    i think using a DAO is not about the question whether a service knows about the underlying mechanism like transactions. In fact a business service DON’T and SHOULDN’T know that it’s method calls usually trigger the spanning or joining of a transaction context it performs within. This is a crosscuting technological concern that should not be managed programatically within a service. Instead you want to use declarative transaction demarcation, so the service is completely unaware that it will run within a transaction.
    The real question to me is, if data access logic should be mixed with business logic. As said in the post entry: I’m not talking about simple CRUD operations (although using Hibernates session directly inside your service comes with just some mentioned consequences like violating dependency inversion principle). Imagine a use case where you’ll use Hibernates Criteria API in order to accomplish a not so trivial search, based on some search criteras the user enters or derived by some kind of business logic inside your service, Would you embedd the building of the Criteria instance (which is a technical implementation detail of the chosen data access strategy) next to your business logic?
    Same with cases when you’ll use HQL (or EJB QL analogical). I rather won’t define my named parameters array or Type array inside my service. I don’t want to expose how to handle with fields that are nullable (may by using nvl() within the HQL) as it’s again a technical implementation detail, that my serivce shouldn’t worry about. Instead those details should be encapsulated in conjunction with an intention revealing, domain related interface which express the services needs in a way that only shows whats needed, leaving the implementation details (the how) behind that abstraction.

    Greetings

    Mario

  15. Jean-Philippe Bouchard Says:

    magle,magle,

    I completely agree with that. Even with an ORM solution like Hibernate, a DAO layer is definitely worth the effort, especially if your querying logic is involved.

    In my project (http://blog.pyromod.com/2007/09/bestcrosswordscom-architecture.html), I use Hibernate and originally I didn’t have a DAO layer, I had an anemic domain model (http://martinfowler.com/bliki/AnemicDomainModel.html) with a service layer sitting in front. The service layer was encapsulating both business logic and data access logic. Since my querying needs were complex, the querying logic accounted for more than 70% of the code in the services layer. Extracting that logic into a DAO layer was the best thing I’ve done. Once I had done that, I started migrating what remained of the business logic into my domain model but that’s another story.

    By the way, I use a generics based DAO layer as outlined here (http://www.hibernate.org/328.html) and even though I could migrate off Hibernate without disturbing the domain model, that was not the primary goal of the layer, it’s just an added bonus…

  16. legolas Says:

    Very good article and very good comments.
    Can some one explain why we need a factory when we have DAO in place?

  17. john Says:

    Good discussion. I don’t want to take anything away from the pro DAO position, but I have a concern in using DAO on top of a JPA EntityManager.

    How can I write a DAO to manage relationships between objects? Can it be written in a way that I can call a getter on my domain object to get a related object? For example, in an order management application, where an Order has many Items, how would I arrange DAO so that the ItemDAO.findItemsForOrder is invoked when I call Order.getItems().

    Thanks,
    John

  18. DAO - it’s not about Layering, it’s about Abstraction! « brain driven development Says:

    […] not about Layering, it’s about Abstraction! February 17, 2009 — Mario Gleichmann Again there were some interesting debates in the near past, which once again discussed the role of the […]

  19. bet365 Says:

    hi I was luck to look for your topic in google
    your post is quality
    I obtain a lot in your Topics really thank your very much
    btw the theme of you blog is really admirable
    where can find it


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: