Announcement Announcement Module
Collapse
No announcement yet.
Pass domain objects to presentation layer, but not to modify them? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Pass domain objects to presentation layer, but not to modify them?

    One paragraph from chapter 1 of "Professional Java Development With The Spring Framework":


    "The Big Picture

    ...Domain objects will typically be passed up to the presentation layer, which will display data they contain, but not modify them, which will occur only within the transactional boundaries defined by the business services layer. ... "

    Q1: So, If I pass the domain objects to the presentation layer, and let the user modify the object's contents directly, then send back to service layer to update db, will there be any problem?

    Q2: What could be the best practice to organize the CRUD functions? Read the Domain Objects in the service layer then transfer them to Transfer Objects to presentation layer?

    Thanks for your any opinion!

  • #2
    There are have been lots of threads about this debate. I would have a look through the previous threads, they might answer your questions.

    http://forum.springframework.org/showthread.php?t=30251
    http://forum.springframework.org/showthread.php?t=19429

    Comment


    • #3
      Originally posted by leonchen View Post
      One paragraph from chapter 1 of "Professional Java Development With The Spring Framework":


      "The Big Picture

      ...Domain objects will typically be passed up to the presentation layer, which will display data they contain, but not modify them, which will occur only within the transactional boundaries defined by the business services layer. ... "

      Q1: So, If I pass the domain objects to the presentation layer, and let the user modify the object's contents directly, then send back to service layer to update db, will there be any problem?
      I think they presentation layer should not be able to modify your domain objects. The fact that you are exposing your domain object in the presentation layer is questionable, but still a preferred choice because creating DTO's is a lot of work.

      So it should be a design guideline: don't modify domain objects in the presentation layer.

      And if you use AspectJ, you can even enforce it.

      Q2: What could be the best practice to organize the CRUD functions? Read the Domain Objects in the service layer then transfer them to Transfer Objects to presentation layer?
      It saves time exposing the domain objects in the presentation layer (instead of writing dto's). So I would choose that option, and apply the design guideline I gave above.

      Comment


      • #4
        Originally posted by Alarmnummer View Post
        I think they presentation layer should not be able to modify your domain objects. The fact that you are exposing your domain object in the presentation layer is questionable, but still a preferred choice because creating DTO's is a lot of work.

        So it should be a design guideline: don't modify domain objects in the presentation layer.

        And if you use AspectJ, you can even enforce it.


        It saves time exposing the domain objects in the presentation layer (instead of writing dto's). So I would choose that option, and apply the design guideline I gave above.
        Or you implement some restrictive interface and expose them in the presentation layer.

        Comment


        • #5
          Originally posted by madtree View Post
          Or you implement some restrictive interface and expose them in the presentation layer.
          Although I agree, I do prefer Peter's AspectJ solution. I program to interfaces anyway thus restricting access, but if its strictly enforced it won't go wrong.

          Comment


          • #6
            Originally posted by Alarmnummer View Post

            ... So it should be a design guideline: don't modify domain objects in the presentation layer.

            And if you use AspectJ, you can even enforce it.


            It saves time exposing the domain objects in the presentation layer (instead of writing dto's). So I would choose that option, and apply the design guideline I gave above.
            Thanks!

            Could you give me a hint, how to expose the domain objects in the presnetation layer for Upating but will not modify domain objects in the presntation layer (and without writing dto)?

            Thanks!

            Comment


            • #7
              Someone suggested having an interface which would be a good idea. Only expose getter methods to the presentation. Peter also said about using AspectJ, this article has an example of that.

              http://debasishg.blogspot.com/2006/0...aky-model.html

              Comment


              • #8
                Originally posted by karldmoore View Post
                Someone suggested having an interface which would be a good idea. Only expose getter methods to the presentation. Peter also said about using AspectJ, this article has an example of that.

                http://debasishg.blogspot.com/2006/0...aky-model.html
                Thanks!

                I think the interface and AOP are trying to enforce the presentation layer not to modify the domain objects.

                But my problem is that, without modifying domain objects, how to send the modified data about the domain objects back to the service layer (and don't use DTO)?

                For example, I have an domain class: Insurance, which has more then 30 properties and complex object relations. Users want to modify the Insurance domain objects' properties, what will be the best practice (and fast programming way) to send the modified properties back to service layer?

                1. create a service method which has more then 30 parameters.
                2. create DTO.
                3. send the domain object to the presentation layer, let the presentation layer directly modify the domain object, and then send back to the service layer.
                4. other?

                Thanks for your any opinion.

                Comment


                • #9
                  Originally posted by leonchen View Post
                  But my problem is that, without modifying domain objects, how to send the modified data about the domain objects back to the service layer (and don't use DTO)?
                  I guess you have to do the one or the other. And I wonder what should be bad about modifying domain objects - as long as you don't write directly to the database. I do not use OSIV at all and I don't think it's a good idea to use it. The service layer has to care about persisting the changes or transactional boundaries in general as already mentioned.

                  Regards
                  Jörg

                  Comment


                  • #10
                    Originally posted by leonchen View Post
                    Thanks!

                    I think the interface and AOP are trying to enforce the presentation layer not to modify the domain objects.

                    But my problem is that, without modifying domain objects, how to send the modified data about the domain objects back to the service layer (and don't use DTO)?
                    Make an object that contains the changes: EmployeeMoveRequest eg.

                    For example, I have an domain class: Insurance, which has more then 30 properties and complex object relations. Users want to modify the Insurance domain objects' properties, what will be the best practice (and fast programming way) to send the modified properties back to service layer?
                    In most cases he only wants to change certain aspects, so try to make an object that contains these changes.

                    This is my preferred way.. but if there is not much logic (unlike in your case I guess) the fastest solution would be to expose the domain objects and just create a update method on your application services.

                    Check the following blog:
                    http://peter.jteam.nl/?p=11

                    1. create a service method which has more then 30 parameters.
                    We both know this is a big no-no.

                    2. create DTO.
                    DTO is not a good name here I guess. But creating some data container that contains the changes would be my preferred solution.

                    3. send the domain object to the presentation layer, let the presentation layer directly modify the domain object, and then send back to the service layer.
                    See the bloglink.

                    Thanks for your any opinion.
                    No problem.

                    Ps: don't take my answers for granted. I'm interested in the subject, but I also make mistakes and have to learn new stuff. So the answers I have given reflect my current understanding and opinion.

                    Comment


                    • #11
                      Originally posted by leonchen View Post
                      I think the interface and AOP are trying to enforce the presentation layer not to modify the domain objects.

                      But my problem is that, without modifying domain objects, how to send the modified data about the domain objects back to the service layer (and don't use DTO)?
                      I have a slightly different view of things. I would not object to modification of domain objects by the presentation layer, so long the modification is abstracted within an appropriate service/domain layer api. The blog link posted above is the one written by me and what it discourages is exposing the implementation of the domain objects in the presentation layer. Instead of using direct setter methods like trade.setValueDate() and trade.setTradeDate(), which exposes the implementation of the domain object *Trade*, we can very well use more domain specific api s like trade.calculateValueDate(). And the domain object instance *trade* can be automagically built from http layer parameters by frameworks like Spring MVC, which will map request parameters ont POJOs that the business logic can operate on directly.

                      HTH,
                      - Debasish

                      Comment


                      • #12
                        I think what the original author is getting at, is how to gather values from the presentation tier and bind them onto the the domain model. If exposing mutators to the presentation is bad, how do you do it.

                        You either allow it or don't. If you don't, your going to have to hold the data in some other container as Peter suggeted and bind it to the model. Is either solution good or bad, I'd love to know that answer. I think its difficult to answer for all cases.

                        Comment


                        • #13
                          Originally posted by karldmoore View Post
                          I think what the original author is getting at, is how to gather values from the presentation tier and bind them onto the the domain model. If exposing mutators to the presentation is bad, how do you do it.

                          You either allow it or don't. If you don't, your going to have to hold the data in some other container as Peter suggeted and bind it to the model. Is either solution good or bad, I'd love to know that answer. I think its difficult to answer for all cases.
                          Interesting thoughts ! In many situations I adopt a mixed approach towards exposing setters and restricting leakage of implementation.
                          What I try to do in the real world is to restrict *those* setters in the presentation layer which are considered direct *implementation* artifacts and introduce new humane api's (may be through an aspect inter-type declaration) that map more closely with the presentation. e.g.

                          Code:
                          class Order {
                              private int orderNo;
                              private List<Item> lineItems;
                              
                              // ...
                              
                              void setOrderNo(int orderNo) {
                                  this.orderNo = orderNo;
                              }
                              
                              void setLineItems(List<Item> items) {
                                  lineItems = items;
                              }
                          }
                          Not all setters are evil and the ones that map closely with the presentation layer can be very well exposed - in fact exposing them allows frameworks like Spring MVC to automatically build up domain POJOs from the http layer parameters. However, if the domain object is a rich one and deserves careful restriction to be imposed to prevent leaking of the implementation, I would go for a mixed mode. And as the blog post indicates, AOP can be very handy in these situations.

                          Typically I would expose setOrderNo() but restrict setLineItems() in the presentation layer and have an extra api introduced instead :

                          Code:
                          void addLineItem(Item item);
                          This may be very well introduced through an aspect as mentioned in the blog post.

                          So the presentation layer allows modification of domain model through the more humane api and does not expose the implementation. Tomorrow if I change the implementation of the domain by changing the List<> to an array, the presentation layer remains unaffected.

                          In summary, introducing new classes that act only as containers is my last option. But unfortunately there are some use cases which force u to do so.

                          I would love to hear what others have adopted for this type of use case. Man, I desperately miss the *best practices guide* of DDD using Spring .

                          Cheers.
                          - Debasish

                          Comment


                          • #14
                            Originally posted by karldmoore View Post
                            I think what the original author is getting at, is how to gather values from the presentation tier and bind them onto the the domain model. If exposing mutators to the presentation is bad, how do you do it.
                            Thanks and yes, this is my problem. And I don't know how to realize these text from [Professional Java Development With The Spring Framework]

                            "Domain objects will typically be passed up to the presentation layer, which will display data they contain, but not modify them, which will occur only within the transactional boundaries defined by the business services layer. Thus there is no need for distinct Transfer Objects, as used in traditional J2EE architecture."
                            (Sorry, I forgot to include the latest paragraph in my first post)

                            If I have to create other objects to hold the modified data, I think these "clone objects" are very similar to DTO.
                            And is CRUD important? yes, most enterprise systems will need some CRUD, and it is boring... and I want to complete these tasks without too much effort.

                            Originally posted by karldmoore View Post
                            You either allow it or don't. If you don't, your going to have to hold the data in some other container as Peter suggeted and bind it to the model. Is either solution good or bad, I'd love to know that answer. I think its difficult to answer for all cases.
                            In fact, since I started to use Spring, I just send the domain objects to the presentation layer directly. I also let the presentation layer send modified domain objects back to the business layer directly.

                            Thanks for Peter's blog, I think 'bypass business logic' is a big problem, so I have to do some business checks before sending the modified domain object back to the DAO layer.

                            After reading above paragraph from [Professional Java Development With The Spring Framework], I am afraid that there will be more potential problems to send modified domain objects back to the business layer.


                            Since Spring encourage us not to use DTO, I also hope to see how to make a robust system without DTO. Or if the DTO (or view objects, or similar 'clone' objects) is really unavoidable, how to make them in the most efficient way?


                            ps. I love Spring, thanks Spring.
                            Last edited by leonchen; Dec 11th, 2006, 07:56 AM.

                            Comment


                            • #15
                              Originally posted by debasishg View Post
                              Man, I desperately miss the *best practices guide* of DDD using Spring.
                              Have to ask Alarmnummer (Peter) very nicely to ask Erik Evans that question when he meets him.

                              Originally posted by leonchen View Post
                              If I have to create other objects to hold the modified data, I think these "clone objects" are very similar to DTO.

                              Thanks for Peter's blog, I think 'bypass business logic' is a big problem, so I have to do some business checks before sending the modified domain object back to the DAO layer.
                              I agree that if it looks like a DTO, and smells like a DTO, then its a........ Fair point! Is it a problem to allow the domain model to be updated? If you ensure the only mutator methods exposed are those which *don't* bypass business logic is that OK? Is that better or worse then having a container to apply to the domain model? Who knows.

                              Comment

                              Working...
                              X