Community   SpringSource   Projects    Downloads    Documentation    Forums    Training   Exchange   Blogs

Go Back   Spring Community Forums > Core Spring Projects > Architecture Discussion

Reply
 
Thread Tools Display Modes
  #61  
Old Feb 22nd, 2006, 01:30 PM
devijvers devijvers is offline
Member
 
Join Date: Sep 2005
Posts: 54
Default Employee persistence question

Regarding the persistence question with the Employee class as an example. I think this is a really bad example for the purpose of discussing domain model design as it's clearly not been taken from a proven design. In my experience you can only have a useful discussion based on a proven design.

For example, is it the responsibility of the fire() method on the Employee class to clean the employee's desk? It's hard to be sure, but Employee is probably an Aggregate and Desk an immutable Value Object. I don't see what functionality would be implemented in the clean() method of the Desk class. A more useful thing to do in the fire() method to me seems to set the desk member variable to null. So the fire() method looks like this:

Code:
class Employee{
   public void fire(){
       setDesk(null);
       setStatus(FIRED);
       setSalary(0);
       setFiredDate(new Date());
    }
}

What's the impact on persistence? If you use Hibernate the relationship between Employee and Desk will be automatically removed.

A comment on the exact role of the Desk class. First I talk about Desk as a Value Object, next I say it's managed by Hibernate as an Entity. Which one will it be? In this use case Desk clearly is a Value Object for Employee, and probably for the entire application. It's not the role of an HR application to manages desks in a database. Even if the HR application does manage desks, this should be implement as a separate module using it's own domain model. In this case you can implement the Desk class as a value object yet configure the class as an Entity in Hibernate.

How to call the fire() method when the FIRE! button is clicked in the web browser? First of all, the Employee that is being viewed should be loaded in the HTTP session (or flow scope is you use Spring Web Flow) to enable Optimistic Locking.

In the controller I would call a EmployeeManager.fire() method. The method looks like this:

Code:
public class EmployeeManager {
   /* setter ommitted */

   public void fire(Employee employee) {
      employee.fire();
      employeeOrmRepository.attach(employee);
   }
}
It makes a lot of sense to me to keep the persistence details out of the domain model in this case, I see no reason why the Employee class should be responsible for updating its state in the database.

Why? Well, I guess there's only one place in the application where an Employee can be fired, for example the Employee detail screen.

Does this answer all questions about persistence and domain models? No. Do we need a catalog of domain models used in real applications for educational purposes? Yes.
Reply With Quote
  #62  
Old Feb 23rd, 2006, 01:39 AM
pearl8 pearl8 is offline
Member
 
Join Date: Feb 2006
Posts: 40
Default

Quote:
Originally Posted by josenyimi
Still struggling where to put logic ?
I hope this read may help:
http://www.springframework.org/node/97

The responsability of
Presentation Layer
Business Layer
Persistence Layer
Domain Layer
Is well explained there.

Important note is that the domain layer is a "cross-layer" layer (not just a layer on top of another layer).

Quote:
"The business layer should be responsible for the following:
* Handling application business logic and business validation
* Managing transactions
* Allowing interfaces for interaction with other layers
* Managing dependencies between business level objects
* Adding flexibility between the presentation and the persistence layer so they do not directly communicate with each other
* Exposing a context to the business layer from the presentation layer to obtain business services
* Managing implementations from the business logic to the persistence layer"

Quote:
"... The domain object layer consists of objects that represent real-world business objects such as an Order, OrderLineItem, Product, and so on ..."


HTH,
José.

I went through this example and here are a few words of caution

a) It is too "Hello World" ish to demonstrate DDD
b) It encourages the anemic domain model with all the code being in the OrderServiceSpringImpl.java and the Order and OrderLineItem to have no behavior.
Reply With Quote
  #63  
Old Feb 23rd, 2006, 08:19 AM
cilativ cilativ is offline
Junior Member
 
Join Date: Feb 2006
Posts: 22
Default

>The business layer should be responsible for the following:
>* Managing transactions
Business, real world transactions yes, but not implementation specific transactions
>* Adding flexibility between the presentation and the persistence layer so they do not directly communicate with each other
That is the responsibility of a controller layer not domain layer
Reply With Quote
  #64  
Old May 2nd, 2006, 05:03 AM
Oliver Schlicht Oliver Schlicht is offline
Member
 
Join Date: Apr 2006
Posts: 56
Default

Hi folks,

been reading this thread with enormous intrest, because im at the Fowler book these days, too. Just wanted to post my 2 cents on two topics you discussed here:

1. The business objects <-> DAO issue
To my understanding business objects should not contain any "data access" access code at all. To me there are 2 important reaseons for that. First, why should BOs know that they are held persistent? So for me its kind of task of the application infrastructure to do this job. If you develop a domain model you abstract "real world" objects into domain objects. So when a Product in the real world doesn't know anything about being saved, why should the domain object?
Second, there is the problem of cyclic dependencies. Your DAO has to know about your domain object. If you domain object has to know about your DAO you've just created such kind of dependency. It makes objects harder to test, harder to deploy, harder to reuse...
I personally use the domain layer as some kind of vertical layer all my other layers (DA, Service, Presentation) use.

2. Domain methods in presentation layer
You've mentioned an intresting problem with using domain objects at presentation level. You want to avoid domain logic methods be called from the presentation layer. I recently thought about introducing an interface (e.g. ProductView) where you only define the methods you want to give access to and let your domain objects implement this interface. As long the methods in the interface are a subset of the domain objects methods, theres no more work to do actually. Now place the Interface into your presentation package and typecast the objects that return from services to that ViewInterface.

ProductView product = (ProductView) someService.getProduct(id);

It's just a brainstorming idea. I haven't tried it so far... should work, shouldn't it?

Regards,
Ollie
Reply With Quote
  #65  
Old May 2nd, 2006, 07:10 AM
mfuller mfuller is offline
Member
 
Join Date: Aug 2004
Posts: 42
Default

Hi,

I agree with #1 and I initially like the concept of having a view specific interface. However, if the interface resides in the presentation layer and your domain objects implement that interface, haven't you made your domain objects dependant on your presentation layer?

Quote:
Originally Posted by Oliver Schlicht
Hi folks,

1. The business objects <-> DAO issue

2. Domain methods in presentation layer
You've mentioned an intresting problem with using domain objects at presentation level. You want to avoid domain logic methods be called from the presentation layer. I recently thought about introducing an interface (e.g. ProductView) where you only define the methods you want to give access to and let your domain objects implement this interface. As long the methods in the interface are a subset of the domain objects methods, theres no more work to do actually. Now place the Interface into your presentation package and typecast the objects that return from services to that ViewInterface.

ProductView product = (ProductView) someService.getProduct(id);

It's just a brainstorming idea. I haven't tried it so far... should work, shouldn't it?

Regards,
Ollie
Reply With Quote
  #66  
Old May 2nd, 2006, 07:20 AM
Oliver Schlicht Oliver Schlicht is offline
Member
 
Join Date: Apr 2006
Posts: 56
Default

You definately would if you'd have to write extra methods in the domain class to implement the interface. What you do here is simply abstract away already existing interfaces of that object. It seems to me a little bit like defining remote and home interfaces for EJBs (uhhh... that ugly word ... But in a pure object oriented way you are right, of course.

I think that the problem is, that if the Service returns a domain object, you have to import it into your presentation class for example. And if you can't force presentation class developers to use the interface, all the fancy interfacing isn't worth a penny

Damn... it looked to good

Regards
Reply With Quote
  #67  
Old May 2nd, 2006, 07:24 AM
mfuller mfuller is offline
Member
 
Join Date: Aug 2004
Posts: 42
Default

Couldn't your services return the View Interface?
Reply With Quote
  #68  
Old May 2nd, 2006, 08:07 AM
Bosmon Bosmon is offline
Member
 
Join Date: Feb 2005
Location: Cambridge, UK
Posts: 37
Default

Quote:
2. Domain methods in presentation layer
You've mentioned an intresting problem with using domain objects at presentation level. You want to avoid domain logic methods be called from the presentation layer. I recently thought about introducing an interface (e.g. ProductView) where you only define the methods you want to give access to and let your domain objects implement this interface. As long the methods in the interface are a subset of the domain objects methods, theres no more work to do actually. Now place the Interface into your presentation package and typecast the objects that return from services to that ViewInterface.

ProductView product = (ProductView) someService.getProduct(id);

It's just a brainstorming idea. I haven't tried it so far... should work, shouldn't it?
The problem with simply using Interfaces here is that most view layers won't respect them, since they typically rely on reflective invocation to back resolution of some form of EL expressions. However, a more firm barrier to access could be supplied by fabricating proxies to represent the domain objects, or else some other form of EL interception.

In the "anaemic" view of course, you would be happy to permit arbitrary modification by your domain objects through view, since this would have no behavioural impact until the modifications were inspected by the service layer. I do accept all the arguments against anaemic models, but am continuing to find they offer a number of practical and design benefits - on the other hand I'm firmly convinced we must make sure not to adopt principles and technologies that rule out the use of "full" domain models.

In general I think some form of declarative proxying ("declarative" used in the sense that Spring offers "declarative" transaction management to contrast with the "programmatic" variety) could be very productive in this area.
Reply With Quote
  #69  
Old May 2nd, 2006, 08:37 AM
cilativ cilativ is offline
Junior Member
 
Join Date: Feb 2006
Posts: 22
Default 2 types of domain objects

When I code domain objects I like to break them into 2 types: regular domain objects( Customer, Address, etc.) and stateful Use Case controllers. I don't break controllers one for every use case. They might be responsible for few related use cases and they use the state and references to regular domain objects to fulfil their responsibilities. I like to move as much as possible domain logic into regular domain objects except data access. Controllers are aware and initiate calls to DAOs or repositories.
Reply With Quote
  #70  
Old Jul 14th, 2006, 01:56 PM
apostiglioni apostiglioni is offline
Junior Member
 
Join Date: Jul 2006
Posts: 6
Default

Hi folks, excelent post. I'd like to share my experiance in a quite big project, with hundreds (or even thousands) of services and tens of business modules.
I also have some architectural and design questions, some related to Spring usage good practices.

The application was built upon business modules, each consisting of these layers:

BUSINESS MODULE
+---------------+
| view |
+---------------+
| communication |
+---------------+
| service |
+---------------+
| domain |
+---------------+
| dao |
+---------------+

* Business modules where divided so as to model different business areas of the client organization.
* Interaction beween business modules was service-driven, with the idea of hiding business details (and model) inside each module. We had some trouble though, in the dao layer, when objects from one module needed to store references to objects from another module.
* The communication layer was completely use-case oriented (see ahead what I mean). This layer consisted basically in dto's and proxies with logic for transforming domain objects to and from the dto's. By use-case oriented I mean that each use case had it's own dto with only extrictly the information needed for the use case. DTO's where first intendend to serve as the clasic pattern suggests, since the view and the application server where in separate machines. They also accomplished an excelent work in decoupling the business domain and the views, flattening complex domain object graphs into simple single objects. Another achievement of this layer was that these dto worked as dettached objects allowing to close hibenrate sessions BEFORE rendering the view.
* The service layer worked properly as a service layer :P, only as a facade of the underlying domain and for transaction demarcation. They where NOT AWARE of the dto's. All the transformations between dto's and model-objects was handled by the communication layer.
* The domain layer consisted in all business logic.
* The dao layer consisted in crud and query operations, with no business logic.

In my experience, the DTO's did a great job in the last two points and I prefer this approach rather than the "Open Session in View" pattern, which is not applicable in a distributed environment. Even if the environment is not distributed, I'd prefer this pattern rather than coupling the view to such low-level implementation issues. The fact that they were use-case specific also draw in a significant performance improvement, compared to initializing the whole domain-graph before detaching. We worked a lot with code generation, to simplify the coding and mantenience of this DTO's.

So, here is are a few questions:
1. Does your view layers interact directly with the domain objects?
2. If so, Don't you think this approach couples the view and the domain too tight? How do you manage the detaching? Do you initialize the complete graph?
3. If not so, do you work with dto's? how do you create them? by hand? code generation? dynamically?
4. Which should be the scope of the application contexts / bean factories (ej: layer, module)? How many of them should exists?
5. Which classes should do de beanFactory.getBean("someBean")?
6.
Quote:
Originally Posted by rebornspirit
The domain model should hold as much as possible domain logic as possible. But sometimes to perform this domain logic, the model needs another dao or service and this is for the moment not simple to implement in Spring. I know they are working on it but it is still in the sandbox and I'm going to wait for it until it is in the releases.
Why do you think that (or what do you mean by) it's not easy to implement that model-objects uses another dao or service? Is it because you cant't inject this dependencies and you don't want your domain object to do something like ServiceLocator.locate(some service) or I'm missing something? Is there any other way?


PS:
Quote:
Originally Posted by rebornspirit
I as just looking at our service and dao and there were so many methods that were just delegating to the dao that I thought I was doing something wrong.
I came across the same situation and was wondering a way of creating dynamic services that just delegate the operations to de daos.
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -5. The time now is 10:07 AM.


Contegix provides first-class managed hosting and partial sponsorship of these forums.

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.