2

I have inherited an application written in Java that uses JPA to access a database. The application uses an design pattern that I haven't come across before and I would really appricate some guidance on why this pattern is used. Like many applications, we have a front end, middleware, and back end database. The database is accessed via DAOs. Each method on the DAO loads a entity-DTO which is just a POJO with nothing but getters and setters and that entity-DTO is then passed into a entity-proper that has other methods that change the entity state. An example [class names changed to protect the inocent]

enum Gender
{
    Male,
    Female
}

class PersonDTO
{
    private String mFirstName;
    private String mLastName;
    private Gender mGender;
    ...

    String getFirstName() { return this.mFirstName; }
    String setFirstName(String name) { this.mFirstName = name; }
    // etc
}

class Person
{
    PersonDTO mDTO;
    Person(PersonDTO dto)
    {
        mDTO = dto;
    }

    String getFirstName() { return mDTO.getFirstName() }
    String setFirstName(String name) { mDTO.setFirstName(name); }
    // and so on

    void marry( Person aNotherPerson )
    {
        if( this.getGender()==Gender.Female && 
               aNotherPerson.getGender()==Gender.Male)
        {
            this.setLastName( aNotherPerson.getLastName() );
        }
        aNotherPerson.marry( this );
    }
}

This is repeated across 30 or so entity classes, doubled to 60 with the DTOs, and I just cant get my head around why. I understand (bits) about seperation of converns and I also understand (bits) about the difference between an EAO based design to say an active record based design.

But does it really have to go this far? Should there always be at least one "DB" object that contains nothing but getters and setters that map to the DB fields?

4 Answers 4

1

Disclaimer: there are varying opinions on this subject and depending on your system's architecture you might not have a choice.

With that said... I've seen this pattern implemented before, not a huge fan of it, in my opinion is duplicates large amounts of code without adding any real value. It seems to be particularly popular in systems with XML APIs like SOAP where it might be difficult to map XML structure directly to your object structure. In your particular case it seems to be even worse because on top of duplicate getFirstName()/getLastName() methods, there is business logic (which belongs in the service layer) coded right into a pojo (which should be a simple data transfer object like the DTO). Why should the pojo know that only people of opposite sex can get married?

To help better understand why, can you explain where these DTOs come from? Is there a front-end submitting data to a controller which then converts it to a DTO, which is then used to populate your entity-proper with data?

Sign up to request clarification or add additional context in comments.

4 Comments

The DTOs are created as a result of web service calls all handled from one class run by timer. it goes off,calls a web service,fills in DTOs,persists them,then creates the "entities" which are held in memory.The front end then accesses the entities and mutates them via controller. As for "Why should the pojo know that only people of opposite sex can get married?" (bad example in 21 century!)-isnt that a core part of OOP?So you can say have a CelebrityPerson that overrides marry() and doesnt take their spouses name?Vs a switch on the type in your service layer that acts depending on the type?
@JamesHobson - The question is why does Person handle marrying? Is there a divorce method as well? How about emailing folks to let them know the divorce has been finalized (now your Person class knows about emails)? The list of methods can get infinitely long as you add new functionality. That is why there should be MarriageService which handles marry and divorce operations, so that POJO doesn't have to know about every scenario in which it gets used. Separation of concern would be the guiding OOP principal here. As far as handling different marriage types, check out the Strategy pattern.
@JamesHobson - I guess it boils down to Person class looking suspiciously a lot like a Service would in a typical N-tier application. Consider writing a unit test. If Person were a service without getFirstName()/getLastName() you'd just test marry(Person person1, Person person2). But in this setup you have to test your setters and getters as well.
Marry is probably a bad example since you dont really "tell" a person to marry and it may involve lots of other ops not just 2 people. What I'm getting into I suppose is the old AnemicDomainModel argument - why cant the domain objects have some methods that change their own state beyond just basic get/set, possibly involving other objects? There is much on SO about all this and I suppose like anything, its just opinion - and one that seems the more I read, the more confused I get ;)
1

It could also be that they are using this just to separate the JPA annotations from the rich domain object.

So I'm guessing that somebody didn't like having JPA annotations and the rich domain object behaviour in one class. Somebody could have also argued that the JPA annotation and the rich domain object should not be in the same layer (because the annotations mixes the concerns) so you would get this kind of separation if you won this argument.

Another place where you'd see this kind of thing happening is when you want to abstract similar annotations away from the rich domain objects (like jaxb annotations in web services for example).

So the intent might be that the DTO serves as sort of the serialization mechanism from code to the database, which is very similar to the intent mentioned here by martin fowler.

1 Comment

Thanks - get that its the why I am looking for in "didn't like having JPA annotations and the rich domain object behaviour in one class"
0

This doesn't appear to be a known pattern.

In general

  • it is common to maintain a separate object to represent the record in the database, referred to as domain object.
  • the CRUD operations on the object are part of a DAO class and other business operations would be part of a Manager class, but none of these classes store the domain object as a member variable, i.e. neither DAO nor Manager carry state. They are just processing elements working on domain objects passed in as parameters.
  • a DTO is used for communication between the front-end and back-end to render data from DB or to accept input from end-user
  • DTOs are transformed to Domain objects by Manager class, where validations and modifications are performed per business rules. Such domain objects are persisted in the DB using DAO class.

2 Comments

The lack of a "Manager" class is I think what is confusing me. Would you say it would be more excected to have something like: PersonManager.marrayPeople(Person person1, Person person2) etc rather than these operations within the entities?
That's right @JamesHobson, the marry method should have been part of a manager class.
0

I have worked on one project where we have DTOs for the sole purpose of transferring information from front-end controller to some facade layer. Then facade layer is responsible for converting these DTOs to domain objects.

The idea behind this layering is to decouple front-end (view) from domain. Sometimes DTOs can contain multiple domain objects for aggregated view. But domain layer always presents clean, reusable, cacheable(if required) objects.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.