Announcement Announcement Module
Collapse
No announcement yet.
Transfer objects? Page Title Module
Move Remove Collapse
This topic is closed
X
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Transfer objects?

    I have a design question: I need objects which contain data that is transfered between the service and the presentation layer. These objects do not belong to the domain model and are not persisted by the DAOs. They are just simple data containers.

    How to call these objects and where to put them in the package structure? My first thought was "Transfer objects", but I am not sure if this is really appropriated...

    Any suggestions?

  • #2
    They are just simple data containers
    Generally you'll try to avoid these unless there's no alternative.

    The packaging should reflect where they're used - if you can do this in the web-tier (and web related packages) this would be cleaner for your application.

    Comment


    • #3
      Thx for your answer. Why should this be avoided?

      I need to do calculations based on data from the domain model. My idea was to perform this calculations in the service layer. The service layer would first access the model data via the DAOs, then do the calculations and finally give back the results in the data containers I mentioned.

      Of course the calculations could also be done in the presentation layer (i.e. the Controller classes), but I think this is not clean neither...

      Comment


      • #4
        Originally posted by dominic
        Thx for your answer. Why should this be avoided?

        I need to do calculations based on data from the domain model. My idea was to perform this calculations in the service layer. The service layer would first access the model data via the DAOs, then do the calculations and finally give back the results in the data containers I mentioned.
        I think these object are part of the business layer: because they are the result of a calculation in the business layer.

        So I would place them in the business layer. The name? Maybe something that ends with Result or Calculation. If you document these objects good it shouldn't be a big issue imho (it is not something ugly).

        Comment


        • #5
          I use transfer objects myself in a client/server app for the presentation layer. This works great performance wise. My structure is like so:

          Domain Objects
          DAO
          Service Layer <>Business Layer
          Transfer Objects
          View Layer

          My transfer objects are pretty much just java beans. I agree with the other replies that there should be no logic in these transfer objects. Getters and setters should be all you need, occassionally you might have a convenience method that does some formatting or combines a bunch of the fields or something mundane but no real business logic should be there. Stick your logic in your domain objects or in a business layer.

          Comment


          • #6
            Originally posted by dominic
            Why should this be avoided?
            Originally posted by J2EE Development without EJB
            ...if we donít want a distributed architecture, theyíre (DTOs are) redundant and harmful, creating an unwelcome impedance mismatch between business services and callers.
            ...
            Donít tolerate fake objects unless thereís no alternative.
            DTOs can pollute you services API, which should deal with domain objects which can be used by all clients.

            Comment


            • #7
              DTOs can pollute you services API, which should deal with domain objects which can be used by all clients.
              I'm doing a Spring course run by Ben Alex (project lead for Acegi Security) this week and am reading Domain-Driven Design by Eric Evans.
              I'm pretty convinced that DTOs in the context of what I am reading now is a good thing. Ben is teaching us that we should be creating applications with rich-domain objects (not anemic ones) where business logic is solely contained in the domain objects, which are not exposed to the web tier at all. Also, transaction demarcation occurs at the Facade, or Service layer, which allows for transparent persistence.

              The way I have been doing projects recently involves, typically, the web controller calling a service method to return a domain object. At this point the transaction has ended. I make changes to the domain object and then call another service method passing in the domain object, such as an update method to persist the data again in another transaction.

              With domain-driven design architecture, the domain objects themselves should be responsible for maintaining their own integrity and should not be aware of the persistence mechanism nor the the service or facade layer they're behind. Also, if a facade method retrieves a domain object from the database using Hibernate, for example, and if the service method is wrapped in a transaction, then any changes made in the domain object are persisted automatically when the tranaction has ended - ie working with live objects versus detached objects like the way I used to do it

              My packages were basically infrastructure driven. I had a DAO package, a services package and a business or domain package, and then subpackages under each for each business object or concern.
              My code will now be structured in vertical slices, which model business problems. For example, I have am employee package, which contains:
              • an Employee domain object (DO) containing all the business logic for an employee
              • EmployeeDto, which is exposed to clients, mainly web controllers in my case. The Dto basically reflects the domain object but has purely getters and setters of the attributes of the domain object they represent. (use Dozer to do the mapping between Dto and DO - dozer.sourceforge.net)
              • EmployeeFacade - service interface containing methods that the web controller can call (find, create, update, delete etc)
              • EmployeeFacadeImpl - implementation - ultrathin, no business logic at all
              • EmployeeRepository - a DAO interface which has methods like makePersistent (we're still dealing with objects here, not database tables) and makeTransient (which translates to deleting from database - we can't delete an object!)
              • EmployeeRepositoryImpl - a Hibernate implementation
              • .hbm.xml - Hibernate mapping files
              • any business exceptions (runtime) that need to be thrown for the web tier to catch if necessary

              Code structured in this way can make use of java's package protected security as well. To model a new business domain problem, I can simply copy the vertical slice package and change the code quite easily.

              I'm new to this, so please forgive me if I've mixed my jargon up, but this architecture combined with Spring is a breeze and a pleasure to implement

              Alan
              Last edited by Alan Stewart; May 17th, 2006, 06:03 AM.

              Comment


              • #8
                Design

                Alan - to me, what you're really talking about is how you implement your Employee service interface, which you call your EmployeeFacade. Am I right in guessing that clients (e.g. a web controller) deal strictly with the EmployeeFacade, and they use the EmployeeDto as an object for receiving and sending data? If so, then your service design is really the same as what I think a lot of folks do, and that's they have an Employee domain object and an EmployeeManager or EmployeeService, where the latter defines all of the operations useful to clients. Business logic would reside in the latter's implementation, and domain logic would reside in the Employee domain object, but there may not be any real domain logic.

                I consider domain logic to include both the definition and behavior of the domain, where neither is likely to change, and where the definition is often the hardest part to define, and thus quite valuable. You could probably reuse that definition across multiple applications, so it's hardly an "anemic" class.

                A domain object that would have a lot of behavior would be a Coordinate class, as it would include useful operations such as returning radians/degrees, returning the distance to another coordinate, returning a vector representation of itself, etc. Across applications and business, those operations will never change - they're native to the domain.

                So anyways - I think what you describe sounds fine, but I see it more as a different implementation approach for implementing your Employee service interface. Ultimately, all your callers care about is what's in the EmployeeFacade interface, and that's the design that really matters.

                Comment


                • #9
                  Originally posted by robrudin
                  Alan - to me, what you're really talking about is how you implement your Employee service interface, which you call your EmployeeFacade. Am I right in guessing that clients (e.g. a web controller) deal strictly with the EmployeeFacade, and they use the EmployeeDto as an object for receiving and sending data? If so, then your service design is really the same as what I think a lot of folks do, and that's they have an Employee domain object and an EmployeeManager or EmployeeService, where the latter defines all of the operations useful to clients. Business logic would reside in the latter's implementation, and domain logic would reside in the Employee domain object, but there may not be any real domain logic.
                  Yes, clients just deal with the facade - the same as I used to do it, but with the difference that the service or facade implementations do not do any adjustments to the domain objects at all. The DOs do not know about the facade either . Also, using the vertical slice approach prevents any client from accessing the DOs directly if the setters and constructors of the DO are package protected. Moreover, changes in the state of the DO are handled in the one (transaction-wrapped) call to the facade., rather than for example, a 2 step process now where I get the DO in one transaction and then update it in another.
                  Cheers
                  Alan

                  Comment


                  • #10
                    Very nice architecture, Alan. I'm also reading Domain Driven Design, and your approach is along the lines of what I was considering for my project as well.

                    One concern I have, however, is the package protection limiting the interaction between different rich domain objects. The natural solution to this is of course to put all domain objects that need to call each others' methods directly in the same package (as in DDD figure 7.8). This could, however, result in very large, and at least in my mind, cluttered packages if you have to include all the infrastructure classes as in your employee example. Is this just something that I need to "get over" or are there any neat solutions that you have thought of?

                    One idea I have is to make all methods on domain objects public and use AOP to limit direct access to them from the web tier, instead of using package scoping. That way all the infrastructure classes could go in subpackages that aren't prevented from calling the domain methods (employee.persistance, employee.exception etc.), and the main packages become less cluttered...

                    This might do away with the need for DTOs in the web tier as well, since you should be able to use the real domain objects (but limited by AOP to only getter/setter methods). That might mess up transaction demarcation and stuff done by the Facade though, not sure.

                    I'm just learning this as well.... any thoughts?

                    /Erik

                    Comment


                    • #11
                      Very nice architecture, Alan. I'm also reading Domain Driven Design, and your approach is along the lines of what I was considering for my project as well.
                      Thanks Erik, but the credit has to go to Ben Alex of Acegi for the implementation framework.

                      One concern I have, however, is the package protection limiting the interaction between different rich domain objects. The natural solution to this is of course to put all domain objects that need to call each others' methods directly in the same package (as in DDD figure 7.8). This could, however, result in very large, and at least in my mind, cluttered packages if you have to include all the infrastructure classes as in your employee example. Is this just something that I need to "get over" or are there any neat solutions that you have thought of?
                      I've not found this a problem so far. Each domain object has a private no argument constructor to satisfy Hibernate and a constructor taking in the mandatory arguments. If these are immutable, then only getters are provided. If there are other attributes that are optional and mutable, then public setters are provided as well, which also check the content for null etc. Thus, for example, if my Employee object requires it's Cost Centre (which is another persistable entity in a different package) to be changed then the cost centre setter on Employee can be called from within the model or from the facade.

                      My facades still only deal with accepting and returning DTOs to and from the web client. It is already possible to use Acegi Secuirty (via AOP) to limit access to methods. I'll be looking into this as a possibility to tighten up the security.

                      Also, when designing a new DO, declare each attribute with a javadoc comment above to say whether it's mandatory or optional, mutable or immutable. It helps a lot to then determine what constructors and what getters and setters to provide. It ensures that each DO will always be in a consistent correct state.

                      Cheers
                      Alan
                      Last edited by Alan Stewart; May 23rd, 2006, 08:05 AM.

                      Comment


                      • #12
                        Originally posted by aks
                        I've not found this a problem so far. Each domain object has a private no argument constructor to satisfy Hibernate and a constructor taking in the mandatory arguments. If these are immutable, then only getters are provided. If there are other attributes that are optional and mutable, then public setters are provided as well, which also check the content for null etc. Thus, for example, if my Employee object requires it's Cost Centre (which is another persistable entity in a different package) to be changed then the cost centre setter on Employee can be called from within the model or from the facade.
                        Sounds sensible. One question though: Is every persistable entity defined in its own package, or do you have larger packages that contain related entities?
                        Originally posted by aks
                        My facades still only deal with accepting and returning DTOs to and from the web client. It is already possible to use Acegi Secuirty (via AOP) to limit access to methods. I'll be looking into this as a possibility to tighten up the security.
                        I'll definitely be taking a closer look at Acegi for limiting method access. I'm still not sure that the DTOs are necessary if some mechanism (e.g. Acegi) is used to limit access to non-getter/setter methods on the DO, though. Especially if validation is done directly by the DO. Or am I missing something?
                        Originally posted by aks
                        Also, when designing a new DO, declare each attribute with a javadoc comment above to say whether it's mandatory or optional, mutable or immutable. It helps a lot to then determine what constructors and what getters and setters to provide. It ensures that each DO will always be in a consistent correct state.
                        Very nice

                        Cheers
                        Erik

                        Comment


                        • #13
                          In my experience having transfer objects that mirror the domain objects isn't really necessary and leads to a more "bloated" design than exposing the DOs directly. You seem to need more sevice layer methods when using TOs as the front-end can't call the business logic on the DOs.

                          Also, in one project I worked on where I implemented transfer objects, I found the most annoying thing I had to do was constantly convert between TO and DO. This was especially annoying when returning large amounts of transfer objects - in this case it was search results and there could be up to 500 documents returned. So you'd need to convert your SearchResultsDO to a SearchResultsTO which meant converting all the DocumentDOs to DocumentTOs. As you can imagine this had a detrimental effect on performance, although not enough to make the app unusable.

                          I think transfer objects could be useful if your front-end needs certain information collated from several DOs, so then you haven't got the DO->TO mirroring going on, but I can't think of too many situations where this would be the case.

                          Comment


                          • #14
                            Sounds sensible. One question though: Is every persistable entity defined in its own package, or do you have larger packages that contain related entities?
                            Generally, yes - they're called vertical slices. I do have sub-packages that contain "components" that are DOs that do not have a persistence identifier of its own, eg an Address object that has attributes of street number, name postcode etc that is an attrubute of Employee. Or enums.

                            I'll definitely be taking a closer look at Acegi for limiting method access. I'm still not sure that the DTOs are necessary if some mechanism (e.g. Acegi) is used to limit access to non-getter/setter methods on the DO, though. Especially if validation is done directly by the DO. Or am I missing something?
                            In my experience having transfer objects that mirror the domain objects isn't really necessary and leads to a more "bloated" design than exposing the DOs directly. You seem to need more sevice layer methods when using TOs as the front-end can't call the business logic on the DOs.
                            DTOs in this architecture are designed to be used as form backing objects in Spring MVC. Domain objects should manage their state integrity. It is impossible to instantiate a DO unless all mandatory arguments are provided to a constructor. This may prove more difficult if they are used in the web tier.

                            So you'd need to convert your SearchResultsDO to a SearchResultsTO which meant converting all the DocumentDOs to DocumentTOs. As you can imagine this had a detrimental effect on performance, although not enough to make the app unusable.
                            Dozer does a very good job here.

                            The architecture is not prescriptive that a DTO should necessary exist for every DO in the system, but it is prescriptive that a DO should never be returned from a facade or used outside a unit of work.

                            Alan

                            Comment


                            • #15
                              Originally posted by aks
                              The architecture is not prescriptive that a DTO should necessary exist for every DO in the system, but it is prescriptive that a DO should never be returned from a facade or used outside a unit of work.
                              I much prefer to return the DO from the service layer complete with state and behaviour rather than convert it to a TO and strip that behaviour out. How do you provide access for the front-end to that behaviour you've removed? You could take it out of the DO and move it to the service layer but you're edging towards an anemic domain model with that approach. Alternatively you could have the service layer call the DO method, but this still bloats the code slightly.

                              I'm much in favour of the keep-it-simple approach and the less code the better.

                              Comment

                              Working...
                              X