سؤال

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?

هل كانت مفيدة؟

المحلول

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?

نصائح أخرى

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.

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.

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.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top