Page 1 of 9 123 ... LastLast
Results 1 to 10 of 82

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

  1. #1
    Join Date
    Oct 2005
    Location
    Belgium
    Posts
    87

    Default Book: "Domain driven design" implemented in Spring

    I recently started reading the book "Domain driven design" and I would like to start a little discussion here about how to implemented a good layered design, especially input from people who also read the book.

    Let me start by telling you that I also made the fault of making my domain model looking like the anemic model. I guess the influence of using EJB's inthe past was greater than I thought ... So to gain some more insight in the way a "good" domain model should be designed I started reading the book I mentioned above.

    So this is the architecture I had before ()

    controller
    ---
    usecase
    ---
    service
    ---
    domain
    ---
    dao

    Now let me explain
    - Controller has the only responsability to put an get data from the screen / form. The controller gets his business data from a class in the use case layer, also the submission of data will be handled by that use case class.
    - Usecase is responsible for handling, like the name indicates, use case functionalities. It is actually a facade to hide multiple service activities behind one method.
    - Service layer handles everything what is beneed its layer, so it is responsible for crud operations and also for "service" operations. So it wraps multiple daos. Business logic and validation is handles by this layer
    - Dao has only crud operations, no validation, no logic, just orm mapping
    - Domain = anemic model ... no business logic

    So after reading (I'm only half way) I'm thinking of using architectures like

    controller
    -------------------
    Usecase
    -------------------
    service | repository
    ------- -----------
    domain
    ---------- DAO
    -------------------

    - So for now I would keep the concept of a use case layer., but instead of only accessing the service layer it can now also access the repository
    - The service layer has now only "service" functionality, so no explicit crud operations, so its responsability is now more clear. The service layer cannot call the dao directly for crud but should use the repository.
    - The crud operations on the database have been move to the repository which also handles the extra business / domain logic (This is the logic that was difficult to implement directly in the domain class, I'll come back on this later)
    - The dao still only holds the crud operations with orm mapping, no logic there.
    - The domain has now been extended by more logic in the methods, and extra classes in its package that do what is called in the book "specifications pattern". These specifications can be validation on the domain object or extra logic that was difficult to put directly into the domain layer. This extra logic now belongs all to the domain layer but will be handled by the repository.

    I'm still halfway in the book but seperating the service and repository seems a good idea, also making use of "specifications" is helping me put more logic in the domain layer that was before not 100% clear how to implement it directly into the domain object.

    So anyone else who read the book or wo has suggestions.

    I'll keep posting some thoughts on this topic when I found useful stuff in the book

    I also found an interesting article about a generic dao http://blog.hibernate.org/cgi-bin/bl.../08#genericdao, I still need to read it a second time to see if it can be used to really make a generic dao. For now I redefine my crud operations for each domain model, perhaps this can make it more easily.

    Grtz

  2. #2
    Join Date
    Aug 2004
    Location
    The Netherlands
    Posts
    160

    Default

    Interesting post, I will be monitoring this thread and hope to contribute as well in the nearby future. I own the book as well, I am looking for time to start reading it. Therfore it is hard to comment on your post. But I am curious about the sepertion, of your service and repository layer. Sounds just like a special service to me, not really a seperate layer. Triggers me more to start reading the book :-)

  3. #3
    Join Date
    Oct 2005
    Location
    Belgium
    Posts
    87

    Default

    Jettro,

    If that doesn't trigger you ... what about terms like anti-corruption layer
    Sounds hot doesn't it!

    About the seperation:
    What's in a name, I have a service "layer" and a repository "layer", I found that those two approaches belong side by side. Perhaps using the term "layer" is somewhat misleading.. perhaps pattern is a better name?

    So in that case I'll have a service and repository pattern

    Grtz

  4. #4
    Join Date
    Oct 2005
    Location
    Belgium
    Posts
    87

    Default Module pattern

    Recently I posted some remarks about the best way to handle modules in Spring. Instead of having 1 project its its always better to have multiple independent building blocks that you make use of when designing your application.

    So following the "module' pattern from the book I guess that each module should represent an aggregation, clearly defined by its boundaries. The module name could be the for example the same as the root aggregation.

    I find the isolation of aggregations into modules very interesting when writing unit tests. When each module has its own Spring application context configuration, unit and module (integeration) tests really mark clear boundaries.

    Dividing the Spring context files up into service, repository, dao, ... makes it easier to test because for example unit testing my dao layer needs to load the hibernate session and dao bean from the context files. When you have 1 context file per module the test will take much longer because all the other beans must be loaded.

    Anyone out that has good experience with modules and a good way to unit test?

  5. #5
    Join Date
    Nov 2004
    Location
    Hilversum - The Netherlands
    Posts
    1,054

    Default

    A few remarks about your design.

    The Service layer doesn`t have the same scope as the gui/domain/dao layers. It is a sublayer in the domainlayer, that sits on top of the domain model. It is responsible for providing a clear api (a facade) but it also is very usable for adding transactions/security. The ServiceLayer is use-case oriented, so you don`t need an extra Use-case layer.

    - The service layer has now only "service" functionality, so no explicit crud operations, so its responsability is now more clear. The service layer cannot call the dao directly for crud but should use the repository.
    The service layer has all the methods clients are going to use. So the service-layer does have a lot of crud-operations (although most calls can be forwarded to the dao).

    But I don`t see how the repository fits in. I know the 'Repository' from the 'Patterns of Enterprise Application Architecture', but they are for entity storage and with an or-mapper like hibernate, you don`t need to write them anymore.
    Last edited by Alarmnummer; Nov 7th, 2005 at 05:43 AM.

  6. #6
    Join Date
    Oct 2005
    Location
    Belgium
    Posts
    87

    Default

    I agree with you that service layer is already use-case oriented, but in that way that its use case functionalities that it offers is limited to the underlying domain model. So in our application we have multiple services, when a creen action is taking, the logic behind is needs to perform multiple tasks, spread around in multiple services. So we created a use case layer that actually handles end user / end application use-cases scenarios. That way we hide the multiple services we need from the mvc controller. The mvc controller only has one dependency and that is our use case layer.

    Secondly, about the seperation between the service and repository class. I was just reading through the book and keeping an open mind... so here some thoughts:

    - The DAO layer should not contain ANY business logic, its only responsability is to handle the ORM mapping
    - 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.
    - So were do we put the logic, for now, that we cannot put in the domain model but that is part of the model? In the book these problems are handled by the Specifucation pattern. The specification pattern is used to solve problems like business logic validation, logic that cannot be placed in the domain model, ... . Can these business logic validations, and other specifications go in the service layer or not? I gues that all these kinds of specifications can go into the service layer for my part ... 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 see service as something on top of the domain, logic that realy does not belong t the domain model itself, I see specifications as part of the domain model so perhaps mixing these two in the same layer (services) is not best idea?

    I'm still reading the book, but for now I find the specification pattern nice to have, but still not sure about the repository layer, thats way I posted this message to see how people layer they apps.

    Feedback would be nice

  7. #7
    Join Date
    Nov 2004
    Location
    Hilversum - The Netherlands
    Posts
    1,054

    Default

    first a disclamer:
    anything I say can`t be hold against me in a court of law. I`m also learning about this subject and I don`t have a lot of practical experience. So it could be that I`m wrong.

    Quote Originally Posted by rebornspirit
    I agree with you that service layer is already use-case oriented, but in that way that its use case functionalities that it offers is limited to the underlying domain model. So in our application we have multiple services, when a creen action is taking, the logic behind is needs to perform multiple tasks, spread around in multiple services. So we created a use case layer that actually handles end user / end application use-cases scenarios.
    I think you mean a service layer when you say use-case layer. Service layer shouldn`t contain much logic and the service layer is the place to add transaction/security. If you need to combine different services to create a new piece of functionality, this new peace of functionality also is a service. And if those other 'lower' services only are called from 'higher' services, I think it is questionable if those lower services should be called service.

    - The DAO layer should not contain ANY business logic, its only responsability is to handle the ORM mapping
    true.

    - 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
    true.

    extra:
    It should contain logic, but you don`t need to place all logic into domain objects. Sometimes it is better to move the logic to a different class (in your domain layer).

    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.
    This is true. I also have commented on this problem a couple of times.

    - So were do we put the logic, for now, that we cannot put in the domain model but that is part of the model?
    There is a servicelocator your domain objects can use to retrieve dependencies.

    In the book these problems are handled by the Specifucation pattern. The specification pattern is used to solve problems like business logic validation, logic that cannot be placed in the domain model, ... . Can these business logic validations, and other specifications go in the service layer or not?
    The service layer shouldn`t contain much logic. It`s only goal is to provide a facade (easy api) where transactions and security can be coordinated. You also could add the application logic in a service object, but the domain logic belongs to the domain-layer.

    I gues that all these kinds of specifications can go into the service layer for my part ... 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.
    Nope.. I don`t think you are doing anything wrong. The Service layer will contain a lot of CRUD operations that can be forwarded to 'lower' objects without any extra operations. But this approach is better than direct access (using a dao in a MVC-controller for example) because it will be difficult to introduce a service layer later.

    [edit]
    for my part
    Nice translation to english Dead giveaway you speak dutch

    - I see service as something on top of the domain, logic that realy does not belong t the domain model itself, I see specifications as part of the domain model so perhaps mixing these two in the same layer (services) is not best idea?
    It is on top of your domain model. Why? If the Service was a true Layer, the Layer on top of the Service (gui-layer for example) shouldn`t know about structure below the Service layer (the Domain layer). And another reason is: the domain layer is on the same abstraction level as the service layer and with layering this isn`t the case.
    Last edited by Alarmnummer; Nov 7th, 2005 at 07:21 AM.

  8. #8
    Join Date
    Oct 2005
    Location
    Belgium
    Posts
    87

    Default

    Thanks for the reply

    Could you explain by usng the small example below where you should put the business logic (the one that was not possible to put in the domain layer) because of dependecies):

    So what you are saying is that I should just use the following structure:

    Code:
    Service ---> dao ---> database
    and in between the dao and the service layer, the domain floats. But where would you validate and add business logic, for example if we would have the simple update method

    Code:
    DomainObject update(DomainObject o)
    We would have an update method in the dap, that just checks that the object to update is not null for example and that is has an id. But where would you put the validation and other business logic that is needed to update the object. If you say that the service should not contain that logic and the dao should definitly not contian that logic ... where should this logic go?

    If you would drawn a layered diagram of your application, how would you draw it?

    Code:
    service - dao -domain
    or

    Code:
    service
    dao domain
    or ...

    Because perhaps I have a wrong view on what "layered" means? I always talked about a layer that is something that hides what is beneed. So a service hides that it is using some king of dao (hibernate/jdbc...)

    It would be great if you could tell me (with an example ... ) what the true meaning of a layer is, because the more I seem to work with "layered" design, to more I get confused

    But I'm learning

  9. #9
    Join Date
    Nov 2004
    Location
    Hilversum - The Netherlands
    Posts
    1,054

    Default

    Quote Originally Posted by rebornspirit
    Thanks for the reply

    Could you explain by usng the small example below where you should put the business logic (the one that was not possible to put in the domain layer) because of dependecies):
    It should be put in the domain layer, but a (bad) example of domain logic in the service is:

    Code:
    EmployeeService{
        void fire(Employee employee){
            Desk desk = employee.getDesk();
            desk.clean();
            employee.setStatus(FIRED);
            employee.setSalary(0);
            employee.setFiredDate(new Date());
            employeeDao.save(employee);
        }
    }
    So what you are saying is that I should just use the following structure:

    Code:
    Service ---> dao ---> database
    No:

    DomainLayer -> Data accesslayer -> Database

    the service layer only is a very small layer that is part of your domain layer.

    If you focus on the domain layer, you see:

    ServiceLayer : DomainLayer

    But where would you validate and add business logic, for example if we would have the simple update method
    It should be part of the domain model:

    Code:
    class Employee{
    
       void setSalary(int amount){
            Validator validator = ... retrieve salary validator
            validator.validate(amount);
            _amount = amount;
       }
    }
    But if you use a weblayer, this logic is repeated (ugly) in the weblayer. I think people should stop writing weblayers for applications, because it makes everything so complex

    We would have an update method in the dap, that just checks that the object to update is not null for example and that is has an id. But where would you put the validation and other business logic that is needed to update the object.
    Example:

    Code:
    class Employee{
      void fire(){
            Desk desk = getDesk();
            desk.clean();
            setStatus(FIRED);
            setSalary(0);
            setFiredDate(new Date());
            employeeDao.save(employee); //this one is questionable.
        }
    }
    UI -> Domain -> DAO.

    Because perhaps I have a wrong view on what "layered" means?
    in "Patterns of Software Architecture" there is a great topic about layering.

    But I'm learning
    I`m also learning. I have to get a better understanding on this subject and a good discussion helps a lot.
    Last edited by Alarmnummer; Nov 7th, 2005 at 08:09 AM.

  10. #10
    Join Date
    Oct 2005
    Location
    Belgium
    Posts
    87

    Default

    Thanks for the reply,

    I always thought when you were talking about the domain layer that you where talking about something above the domain model, but know I see that the term domain model and domain layer are the same... sometimes mixed terminologie can lead also to misunderstanding.

    Correct me if I'm wrong here

    Code:
    class Employee{
    
       void setSalary(int amount){
            Validator validator = ... retrieve salary validator
            validator.validate(amount);
            _amount = amount;
       }
    }
    I agree that this is the best way, the problem is that Spring has no nice way to handle this and I cannot use the solution in the sandbox. So I guess that you would move the validation to the service, corect?

    Grtz

Posting Permissions

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