Page 2 of 3 FirstFirst 123 LastLast
Results 11 to 20 of 21

Thread: Transfer objects?

  1. #11
    Join Date
    Dec 2005
    Posts
    930

    Default

    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 at 08:05 AM.

  2. #12
    Join Date
    May 2006
    Location
    Stockholm, Sweden
    Posts
    37

    Default

    Quote 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?
    Quote 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?
    Quote 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

  3. #13
    Join Date
    May 2006
    Posts
    7

    Default

    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.

  4. #14
    Join Date
    Dec 2005
    Posts
    930

    Default

    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

  5. #15
    Join Date
    May 2006
    Posts
    7

    Default

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

  6. #16
    Join Date
    May 2006
    Posts
    16

    Default Additional Naming Convention...

    Quote 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 would add this point to your design:

    Don't use that "DTO" word as the suffix of your POJO. Use something meaningful. Instead of "CustomerDTO" you can use something like "CustomerVisualization" or so. This makes your "DTO" as the part of your POJO domain model.

    Check this discussion in TSS for more information:
    http://www.theserverside.com/news/th...d=34278#172706

    Lofi.
    EJOSA

  7. #17
    Join Date
    Dec 2005
    Posts
    930

    Default

    Don't use that "DTO" word as the suffix of your POJO. Use something meaningful. Instead of "CustomerDTO" you can use something like "CustomerVisualization" or so. This makes your "DTO" as the part of your POJO domain model.
    The "DTO" term is a legacy of EJBs, is it not? I'm all for renaming it -
    "CustomerService" has become CustomerFacade, CustomerDao has become CustomerRepository anyway.

    One of the practical difficulties I've battled with this week is to do with a "lookup" table containing attributes that the DOs need. The lookups have their own persistence lifecycle but the data is quite static. My employee table contains integer references to the lookups its stores. To create a new employee requires all the lookups to be retrieved from the repository as DTOs and passed into the constructor for the Employee DTO and then passed to the facade, to create the DO. Likewise, changes to lookup entities in the employee also need them to be retrieved and then set into the employee object. This has been a bit of a nightmare, as I could have done it using components, or even JDK5 enums. The schema is new, but was enforced by our data modeller. Maybe I'm doing it the wrong way but I can already see the benefits of using domain objects and vertical slices. I can quickly copy a slice into a new package and make modifications, and then plug in the MVC layer.

    Regards
    Alan

  8. #18
    Join Date
    May 2006
    Posts
    16

    Default

    Quote Originally Posted by aks
    The "DTO" term is a legacy of EJBs, is it not? I'm all for renaming it -
    "CustomerService" has become CustomerFacade, CustomerDao has become CustomerRepository anyway.
    I meant, just don't use those *suffixes* at all...
    - No CustomerDTO at all... no CustomerService or CustomerFacade at all
    - Instead use "real business name" something like CustomerVisualization or CustomerDetail, CustomerActivity, etc.

    Quote Originally Posted by aks
    One of the practical difficulties I've battled with this week is to do with a "lookup" table containing attributes that the DOs need. The lookups have their own persistence lifecycle but the data is quite static. My employee table contains integer references to the lookups its stores. To create a new employee requires all the lookups to be retrieved from the repository as DTOs and passed into the constructor for the Employee DTO and then passed to the facade, to create the DO. Likewise, changes to lookup entities in the employee also need them to be retrieved and then set into the employee object. This has been a bit of a nightmare, as I could have done it using components, or even JDK5 enums. The schema is new, but was enforced by our data modeller. Maybe I'm doing it the wrong way but I can already see the benefits of using domain objects and vertical slices. I can quickly copy a slice into a new package and make modifications, and then plug in the MVC layer.
    Is there any possibilities to generate those standard methods? I would take a look at AndroMDA for this stuffs (components generation, generative software development), see this thread:
    http://forum.springframework.org/sho...t=24660&page=2

    Cheers,
    Lofi.

  9. #19
    Join Date
    May 2006
    Posts
    4

    Default

    Quote Originally Posted by dewanto

    Don't use that "DTO" word as the suffix of your POJO. Use something meaningful. Instead of "CustomerDTO" you can use something like "CustomerVisualization" or so. This makes your "DTO" as the part of your POJO domain model.
    This is actually what I am doing now. As far as possible I am working directly with the domain objects. Where this is not possible I introduced new POJOs, e.g. an object called "ProjectStatistics" to hold some calculations based on the "Project" domain object. The calculations itself are performed by the business tier.

    The question that remains is where to put them. To make them part of the domain model would mean to put them in the same package as the domain objects. From the model perspective this is quite meaningful an elegant in my opinion. But on the other side this would mix persistable objects with non-persistable ones which might be confusing.

    Another idea is to put them in the package where the corresponding business tier service lies.

  10. #20
    Join Date
    May 2006
    Posts
    7

    Default

    Quote Originally Posted by dominic
    But on the other side this would mix persistable objects with non-persistable ones which might be confusing.
    I don't think it's necessarily a bad idea to have persistent and non-peristent objects in the same package. Who's to say they won't become persistent at some later stage anyway?

Posting Permissions

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