Page 7 of 9 FirstFirst ... 56789 LastLast
Results 61 to 70 of 82

Thread: Book: "Domain driven design" implemented in Spring

  1. #61

    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.

  2. #62

    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.

  3. #63
    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

  4. #64
    Join Date
    Apr 2006
    Location
    Dresden, Germany
    Posts
    483

    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

  5. #65

    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

  6. #66
    Join Date
    Apr 2006
    Location
    Dresden, Germany
    Posts
    483

    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

  7. #67

    Default

    Couldn't your services return the View Interface?

  8. #68
    Join Date
    Feb 2005
    Location
    Cambridge, UK
    Posts
    37

    Default

    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.

  9. #69
    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.

  10. #70

    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.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •