why DAO won't die
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.


Arnon (Comment this)
--> 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 :D
Enjoy your day (Comment this)
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.
(Comment this)
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. (Comment this)
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
(Comment this)
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.
(Comment this)
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 (Comment this)