Entidade para uso de DTO


15

Estive tentando criar um fluxo para um aplicativo Web em camadas básico e estava lendo informações conflitantes online. O que estou tentando descobrir é se ainda há uma vantagem de ainda usar objetos DTO da camada DAO para Service através do uso de algum tipo de mapeador.

O fluxo básico que eu prevejo é o seguinte:

  1. Modelo / formulário de interface do usuário -> Controlador
  2. O controlador converte o modelo em objeto de domínio (entidade)
  3. Objeto de Domínio -> Camada de Serviço
  4. Objeto de domínio -> DAO
  5. DAO -> Objeto (s) de Domínio
  6. Serviço -> UI
  7. A interface do usuário converte o domínio em modelos de interface do usuário

Se o DTO foi seguido, o DAO retornaria um DTO e não a Entidade. Depois de fazer algumas leituras, parece que o DTO se tornou um pouco extinto, pois (pelo menos em Java) as entidades se tornaram POJOs anotadas, o que significa que sua pegada de memória se tornou muito pequena.

É esse o caso ou os DTOs devem ser usados ​​para encapsular completamente os objetos de domínio na camada DAO e, se for o caso, o que a camada de serviço passaria para o DAO?

Muitíssimo obrigado!

Respostas:


20

De acordo com mim, aprovar um POJO persistente, como, por exemplo, um bean gerenciado pela JPA, não é a boa prática.

Por quê?

Eu vejo três razões principais:

  1. Problema potencial com coleções preguiçosas. http://java.dzone.com/articles/avoid-lazy-jpa-collections
  2. A entidade deve conter comportamento (ao contrário de um modelo de domínio anêmico ). Talvez você não queira que sua interface do usuário chame algum comportamento inesperado.
  3. No caso de modelo de domínio anêmico, talvez você não queira expor sua estrutura de modelo à interface do usuário, pois cada nova alteração no modelo pode interromper a interface do usuário.

Prefiro permitir que minha camada de serviço converta entidades para o DTO correspondente nas duas direções. O DAO ainda está retornando a entidade (não é seu trabalho garantir a conversão).


Portanto, se estou entendendo isso corretamente, o serviço lida essencialmente apenas com objetos DTO e atua como intermediário da interface do usuário e do DAO. Além disso, no ponto 3, você ainda precisa converter seu DTO em elementos da interface do usuário viáveis, para que uma atualização de domínio ainda não a interrompa, porque o DTO também precisa de uma atualização.
Dardo # 17/13

1
Os elementos da interface do usuário @dardo SÃO DTO, ou, na pior das hipóteses, devem ser convertidos em DTO antes de chamar alguns serviços no lado do servidor. É provável que o DTO não mude com frequência, há apenas uma adaptação de suas entidades focada nas necessidades da interface do usuário. Além disso, a camada de serviço deve se preocupar com: DTO e entidades.
Mik378

Ah, ok, há o soluço que eu não estava entendendo. O modelo de domínio anêmico é bastante comum onde trabalho, e estou tentando mudar um pouco o paradigma para incentivar uma camada de serviço mais fina. Obrigado novamente!
Dardo # 17/13

@ardo Você pode ler este livro. (ou mostrá-lo para sua empresa;)) Grande grande livro: amazon.com/Implementing-Domain-Driven-Design-Vaughn-Vernon/dp/...
Mik378

na verdade, tenho um presente no Kindle, amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/... boa bastante até agora = D
dardo

13

Uma das razões pelas quais penso que essa discussão surge repetidamente é porque parece um grande problema pegar um objeto com todos os dados necessários e convertê-lo em um objeto que pareça idêntico ou quase idêntico àquele você está entregando.

É verdade, é uma PITA. Mas existem algumas razões (além das enumeradas acima) para fazer isso.

  • Os objetos do domínio podem ficar muito pesados ​​e conter muitas informações inúteis para a chamada. Esse inchaço diminui a velocidade da interface do usuário devido a todos os dados transmitidos, empacotados / não empacotados e analisados. Quando você considera que um EF terá vários links referentes aos seus serviços da Web e ser chamado com AJAX ou alguma outra abordagem multithread, você rapidamente tornará sua interface lenta. Tudo isso atinge a escalabilidade geral dos serviços da web
  • A segurança pode ser facilmente comprometida expondo muitos dados. No mínimo, você pode expor endereços de e-mail e números de telefone de usuários se não os eliminar do resultado do DTO.
  • Considerações práticas: Para um objeto desfilar como um objeto de domínio persistente E um DTO, ele teria que ter mais anotações que código. Você terá vários problemas ao gerenciar o estado do objeto à medida que ele passa pelas camadas. Em geral, é muito mais um PITA para gerenciar do que simplesmente executar o tédio de copiar campos de um objeto de domínio para um DTO.

Mas, você pode gerenciá-lo com bastante eficiência se encapsular a lógica de conversão em uma coleção de classes de conversor

Dê uma olhada no lambdaJ, onde você pode 'converter (domainObj, toDto)'; há uma sobrecarga disso para uso em coleções. Aqui está um exemplo de um método de controlador que faz uso dele. Como você pode ver, não parece tão ruim.

    @GET
    @Path("/{id}/surveys")
    public RestaurantSurveys getSurveys(@PathParam("id") Restaurant restaurant, @QueryParam("from") DateTime from, @QueryParam("to") DateTime to) {

        checkDateRange(from, to);

        MultiValueMap<Survey, SurveySchedule> surveysToSchedules = getSurveyScheduling(restaurant, from, to);
        Collection<RestaurantSurveyDto> surveyDtos = convert(surveysToSchedules.entrySet(), SurveyToRestaurantSurveyDto.getInstance());
        return new RestaurantSurveys(restaurant.getId(), from, to, surveyDtos);

    }

Obrigado pela contribuição, e meu pensamento está na mesma linha =) #
dardo 17/05
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.