I've attached a thread discussed at Matt Raible's www.raibledesigns.com regarding the use of structuring a middle-tier layer (specifically, one where I recommending starting with a single service layer and extracting out a DAO only if you need to.)
-------
Keith said...
- Hey matt - collapsing your dao layer into your biz layer would save you 3 to 4 classes per entity, and probably wouldn't get you slapped (I wouldn't slap you anyway.) Of course, you could also scrap the tests if all you're doing is CRUDing by delegating to Hibernate, but I didn't say that. ;-)
Todd said...
> I was intrigued by Keith's comment about accessing DAO's directly in the business logic. My feeling is that a manager layer is only occasionally necessary when it adds real value/functionality on-top of the DAO layer. Otherwise it's just an unnecessary pass-thru layer sending the model objects right through to the DAO layer without doing anything. Matt, I'm curious what your thoughts and experiences have been regarding when to use a manager layer?
Matt said....
>> The main reason for the Manager layer is to wrap its methods with transactions so that multiple calls to DAOs (in a Manager's method) will take part in the same transaction. I've seen some folks get around this and wrap their Actions (i.e. WebWork) with transactions.
Keith said again...
- Collapsing DAO into biz, keeping transaction demarcation at the biz layer is a viable design worth considering with apps with little to no business logic (CRUDers). Also, no one says you have to create a new DAO implementation for each entity--a single facade for the entire application is fine for a small app. Spring's Petclinic is a good example of this. I generally start with a single biz layer and then extract out a lower-level DAO layer only if I need it, for two reasons: to demarcate transactions for biz operations that span multiple DAO operations (what Matt said), AND to decouple my biz logic workflow from my data access technology (which simply not a concern for apps with little biz logic since the biz logic IS the persistence logic). Note with a single biz layer you can still get transaction demarcation for biz operations spanning multiple DAO calls: just have the public interface implementation (which executes transactionally) delegate to private DAO methods within the biz implementation. Don't introduce more layers than you have to, that's what I say (start simple and scale up by refactoring only if you see the need.)
Todd said again...
>>Isn't one of the goals of AOP in Spring to use interceptors to demarcate transactions (rather than having to create a facade like a Manager) to do transaction demarcation? Or is that approach sometimes too simplistic in practice?
Keith won't shut up...
-Spring has a "TransactionProxyFactoryBean" which at runtime can dynamically proxy any POJO to make it execute in the context of a transaction managed by JTA or by a single JDBC resource, completely transparently to callers. It does this by applying a Transaction Interceptor (around advice) that intercepts main flow of execution, typically beginning a transaction before method execution and committing or rolling it back after method execution. The TransactionProxyFactoryBean also accepts fine grained policies about which methods should be made transactional on your POJO object (and which ones should be excluded), which types of Exceptions should/should not trigger a rollback, and the isolation levels and propogation behaivior to use. Now, with that said, yes, it is possible to demarcate transactions at the web-tier, for example on your controllers. Spring can proxy any java interface (using Dynamic Proxies) or class (using cglib). However, I would not recommend this. It's much cleaner to have a well-defined business layer that captures the business requirements of your application, and demarcate transactions there. I think this central to any application: the web layer (and any other presentation layer like Swing) should be kept thin, delegating to the biz layer for the execution of domain-specific use cases. There are many advantages for doing this: 1. It's clear WHAT your application does (through a well-defined, descriptive business contract), 2. biz and persistence logic is fully decoupled from presentation, 3. because of #2, biz/persistence logic can be tested independently of presentation concerns, and 4. middle-tier people and presenation-people are often different people in practice, and the two layers can be developed independently. As I alluded to previously, I see less value in automating the testing of your controllers when the meat of your application is centralized behind a well-defined business. I see more costs than benefits in defining an additional DAO layer when all your application is is a data entry system (CRUDer).
HTH! :-)
Keith Donald
Core Spring Development Team