DTO: Por que usar uma coisa dessas?

[quote=jakefrog]

Eu sei mano. Oq foi dito lah no começo deste tópico foi. Ao invés de usar DTO usar um MAP ou um XML. É isso q eu to falando.

Ao invés de passar ClienteDTO passar e assim vai…[/quote]

Para a comunicação, seja lá o que vc estiver usando vai ter que ser convertido para XML, JSON, Java Serialization, XXXX.

Isso não tem nada haver com DTO. O ponto do Map foi:

Um Map pode ser convertido tão bem quanto um DTO para um desses acima. Se vc quer apenas agrupar um monte de coisas para jogar para o outro lado, vc pode usar uma Collection pra isso, não precisa criar um objeto agrupador.

Mas isso vai cair no gosto de cada um. Usar um DTO tem vantagens e desvantagens, assim como um MAP. Eu não gosto de ter um milhão de DTO’s na minha aplicação. Vai ter algum esperto que vai jogar eles no meio da lógica e cagar tudo. Eu prefiro MAP. Mas use o que vc preferir e seja feliz ! Acho que não é pecado nem um nem outro… :slight_smile:

Acredito que usar Map, resolve… mas não acredito que seja a melhor solução…
pois como foi falado anteriormente (no forum guj) quando eu coloco alguma coisa no Map, eu não sei nem o que se “esta la dentro”, a não ser que eu saiba o que “eu coloquei”, eu não vou ter um map.getNome(), map.getIdade(); isso pode quebrar o contrato da aplicação e nunca vai dar um erro de compilação se eu errar a grafia (se eu usar MAP e passar name ao inves de nome, não da erro nem nada , ai o cara se perde aos poucos . a O.O se perde…)

Alem que a programação fica massante e redundante…
o cara faz…:

[quote]List<Cliente> clientes = dao.listAll();
List<Map> clienteMap = new ArrayList<Map>();
… dai vcs sabem o resto…(um new map >> alimenta map >> add into list)
código procedural…
[/quote]
e sem falar que a refatoração fica impossivel, se eu quise mudar um nome de algum atributo do cliente… tenho que sair catando os maps, e ir mundando as strings… isso é chato…

Map é uma solução rápida, mais não eficiente…
Bem na minha humilde opinião. =)

Acho que o pessoal está confundindo Alhos com Bugalhos…

Alguns conceitos para embasar meus argumentos:

DTO => É uma "classe/estrutura de dados", serve para: Estruturar dados… Um Map também é uma estrutura de dados… Ambos podem ser usados nas mesmas situações (e devem ser usados apenas em situações bem especĩficas).

XML => eXtensible Markup Language… No contexto da thread serve apenas como formato no qual os dados transitarão na rede… Não compete nem com os mapas, nem com os DTO’s… Ambos podem ser serializados em XML, para transitar na rede. (Normalmente eu uso JSON pq é bem menos verboso).

Fujam de DTO, a não ser quando eles forem usados na fronteira entre duas camadas heterogêneas, em termos de máquinas, ou tecnologia ou coisas assim… Ou seja: Só use DTO’s quando precisar estabelecer uma barreira bem clara para os seus objetos de negócio (a causa dessa fronteira pode ser um requisito de segurança, máquinas diferentes, tecnologias diferentes…). Não os use para tráfegar dados dentro da fronteira da sua própria aplicação…

[quote=diogopontual]
Fujam de DTO, a não ser quando eles forem usados na fronteira entre duas camadas heterogêneas, em termos de máquinas, ou tecnologia ou coisas assim… Ou seja: Só use DTO’s quando precisar estabelecer uma barreira bem clara para os seus objetos de negócio (a causa dessa fronteira pode ser um requisito de segurança, máquinas diferentes, tecnologias diferentes…). Não os use para tráfegar dados dentro da fronteira da sua própria aplicação… [/quote]

Falou bonito Diogo !!! Bom encontrar pessoas que conseguem entender o nosso ponto de vista. Concordo que no meu caso, em todos os aspectos mundanos, isso é raro. O que pode ser bom… ou não…

Minha resposta ao Ricardo:

Posso estar enganado, mas acho que os benefícios apontados pelo Ricardo são ilusórios. Por que?

Não, o OO não se perde mas sai ganhando. Porque vc fica obrigado a usar as entidades na lógica e não um monte de DTO ou MAPs. Não é para usar DTO nem MAP na lógica e sim usar os domain objects (User, Product, etc). Se vc concorda com isso, então a tarefa de FORMATAR o resultado passa a ser da ACTION ou da VIEW. No caso aqui estamos falando de JSON, então cada resposta em JSON terá que ser formatada por um DTO diferente. Talvez vc consiga reutilizar um ou outro, mas vai se tornar uma bagunça de DTOs. O benefício que vc citou de refatoração não se aplica, porque se vc muda “nome” para “name”, vc vai ter que se lembrar de ir lá nos DTOs e mudar getNome por getName. Isso na mão. Ou não? Logo não vejo diferença em usar um MAP. Teria diferença se o seu DTO estivesse espalhado pela aplicação inteira, mas aí o problema seria outro.

Então vc prefere que o DAO já retorne um DTO ??? Errado e impossível, porque dependendo da action / request o cliente vai ter que ser convertido para um DTO diferente. Vc pode ter uns esquemas bem espertos para popular um MAP a partir de um BEAN, pegando só as propriedades que lhe interessam. Usando DTO vc terá que fazer a mesma coisa, pois na minha opinião um DAO nunca deveria retornar um DTO (incluindo MAP que é um DTO genérico).

Posso não estar vendo alguma coisa, mas na minha cabeça com DTO vc tb não tem refatoração. DTO é uma coisa burra, sem lógica, que serve apenas para ESPECIFICAR um objeto. Se o cliente passa a esperar nome ao invés de name, então vc vai ter que catar todos os DTO’s que possuem getName e trocá-los para getNome.

Acho que a confusão parte do seguinte: Não estou propondo usar MAP em tudo que é lugar. Isso realmente seria péssimo. Proponho usar um MAP na hora de FORMATAR um resultado, ou seja, no ULTIMO passo do processo, assim como um JSP é o último passo do processo. Lembrando que isso só se aplica para JSON por cause do problema do lazy loading com reflection.

O que não estou vendo? (posso estar errado)

PS: No final, o Ricardo teve uma idéia melhor do que um MAP. Um BeanView que implementa Map. Por que tem que implementar Map ??? Por que o danado do JSON-LIB sabe transformar map em Json. Mas se não for mapa ele vai procurar por getters pensando que é um DTO. Ou seja, o proprio JSON-LIB, por querer ou sem querer, já assume que vai ter gente usando MAP como DTO genérico.

Só para colocar um pouco mais lenha nessa fogueira, pelo menos no meu caso, a causa que determinou a necessidade de usar DTOs foi:

:arrow: Lazy-loading do Hibernate que faz com que o banco todo seja carregado na view (exagerando claro), dependências cíclicas gerando loop infinito que de alguma maneira surgiu no modelo por culpa do hibernate e do maluco que fez a relação ManyToMany (eu diria por culpa dos dois). O fato inevitável de que para renderizar em JSON o JSON-LIB usa reflection procurando por getters, quando não é map.

Conclusão: como o Diogo falou fuja de DTO sempre que possível. E eu deixo mais uma dica. Se beber muito da mágica do Hibernate não dirija. Ou use iBatis ou JDBC + um query builder/helper.

Caramba, tivemos esse problema aqui na empresa. JPA é muito maneiro, mas a equipe tem que entender direitinho o Lazy Load, e como fazer os relacionamentos. Havia um many-to-many, com as coleções nas duas pontas, e tentava-se serializar uma delas para mandar para um cliente Flex, e tomávamos um StackOverflow na testa… Linda oortunidade para se usar (direito) DTO.

Por uma série de motivos, e por causa dos riscos envolvidos, eu preferi, em um novo projeto, abandonar JPA e utilizar as facilidades que o Spring oferece para a camada de dados, usando JDBC mesmo. Pelo menos está me parecendo mais elegante!!!

Exatamente o mesmo problema que encontrei no projeto aqui.

Exatamente o que faço. Sempre que possível irei abandonar o Hibernate e usar iBatis ou JDBC com query helper. Fica mais limpo, fica mais previsível, fica mais gerenciável, fica mais flexível. Mas ir contra o dogma do Hibernate é uma heresia, vc deve saber disso.

Engraçado como pensamos parecido. Seria legal se trabalhássemos juntos em algum projeto. Entre em contato comigo por email para mantermos o contato. sergio ponto oliveira ponto jr at gmail ponto com.

É uma heresia ir contra o dogma “aprenda a usar corretamente a ferramenta antes de fazer uso da mesma, mesmo que para isso tenha que ler um manual de 200 páginas”.

Certo, vamos ver se entendi o que foi discutido, usar DTO para formatar os dados para determinada resposta é errado, o que realmente me parece errado, independente da reposta o DTO deveria ser igual.
Usar o MESMO DTO para passar dados entre camadas (Negócio/View) seria o correto ? Claro que eu poderia fazer isso usando MAP, mas em meu ponto de vista ficar usando reflection para isso não parece certo, prefiro usar o DTO para isso.
No caso o DTO seria apenas para isso, mostrar / limitar / padronizar os dados enviados da camada de negócio para a view, que formataria a reposta.

Correto?

[quote=maniacs]Certo, vamos ver se entendi o que foi discutido, usar DTO para formatar os dados para determinada resposta é errado, o que realmente me parece errado, independente da reposta o DTO deveria ser igual.
Usar o MESMO DTO para passar dados entre camadas (Negócio/View) seria o correto ? Claro que eu poderia fazer isso usando MAP, mas em meu ponto de vista ficar usando reflection para isso não parece certo, prefiro usar o DTO para isso.
No caso o DTO seria apenas para isso, mostrar / limitar / padronizar os dados enviados da camada de negócio para a view, que formataria a reposta.

Correto?[/quote]

oi,

bom, deixa eu dar a minha opinião

  • se no java tivessemos algo como um struct do C usariamos ele ao invés desses DTO’s ou VO’s ou o que seja… (seria o tal template engine?)
  • é errado pegar um objeto de negócio e colocar um monte de gets e sets nele só para facilitar o “agrupamento” desses dados que serão lidos pelo cliente
  • não gosto de maps por temos que ficar trabalhando com strings como disseram…
  • concordo com a sua ultima afirmação
  • supondo que eu tenha que passar para a minha view informações da Empresa e dos Funcionarios, eu criaria um objeto ViewEmpresaFuncionarios e jogaria nele os
    atributos que eu preciso e passaria para a view, não mexeria na camada de negócio
  • dá uma lida no que o Sergio Taborda falou sobre saco de propriedades

Posso desenterrar o tópico?

Bom, entrei em um projeto onde é usado DTO apenas nos relatórios e nos webservices. E a idéia já é ir migrar o projeto para SOA e usando Rest ao invés de soap.

E a primeira coisa que pensamos foi criar um dto pra todas as entidades, bem como seus “converters”, principalmente para separar, onde o serviço recebe somente dto e devolve somente dto, outro motivo que me apresentaram também foi a questão de tráfego, onde o principal consumidor é mobile.

Só que eu encontro esse tópico apresentando vários contras este pattern, eu vi que o DTO pode não ser o melhor cara para isso, aí eu deixo aqui a pergunta, se realmente ainda são contra o uso de DTO, e melhor ainda, se tiverem sugestões de outro pattern para essa questão. :slight_smile:

[quote=TJvargas]Posso desenterrar o tópico?

Bom, entrei em um projeto onde é usado DTO apenas nos relatórios e nos webservices. E a idéia já é ir migrar o projeto para SOA e usando Rest ao invés de soap.

E a primeira coisa que pensamos foi criar um dto pra todas as entidades, bem como seus “converters”, principalmente para separar, onde o serviço recebe somente dto e devolve somente dto, outro motivo que me apresentaram também foi a questão de tráfego, onde o principal consumidor é mobile.

Só que eu encontro esse tópico apresentando vários contras este pattern, eu vi que o DTO pode não ser o melhor cara para isso, aí eu deixo aqui a pergunta, se realmente ainda são contra o uso de DTO, e melhor ainda, se tiverem sugestões de outro pattern para essa questão. :)[/quote]

REST tem diversas técnicas que incentivam a performance, como cache nativo do protocolo HTTP e gerenciamento de concorrência.

Em compensação, eu acredito que, enquanto o uso de JAX-RS 2 não foi mais difundido, você deve usar DTO’s nos seus serviços REST justamente por causa do HATEOAS (para quem não conhece, é a prática de colocar links para outras ações e entidades relacionadas à corrente).

[]'s

[quote=Alexandre Saudate]

REST tem diversas técnicas que incentivam a performance, como cache nativo do protocolo HTTP e gerenciamento de concorrência.

Em compensação, eu acredito que, enquanto o uso de JAX-RS 2 não foi mais difundido, você deve usar DTO’s nos seus serviços REST justamente por causa do HATEOAS (para quem não conhece, é a prática de colocar links para outras ações e entidades relacionadas à corrente).

[]'s[/quote]

Legal, eu conheci o HATEOAS pelo seu livro de SOA, aliás parabéns pela obra;

E falando de SOA, já queria aproveitar para te perguntar Alexandre, se vc considera uma boa solução (à caminho do SOA) tranformar todos os serviços do Sistema(EJB) em EJB REST, inclusive os que o JSF consome, onde até os ManagedBeans passariam a consumir os serviços via REST também;

[quote=TJvargas][quote=Alexandre Saudate]

REST tem diversas técnicas que incentivam a performance, como cache nativo do protocolo HTTP e gerenciamento de concorrência.

Em compensação, eu acredito que, enquanto o uso de JAX-RS 2 não foi mais difundido, você deve usar DTO’s nos seus serviços REST justamente por causa do HATEOAS (para quem não conhece, é a prática de colocar links para outras ações e entidades relacionadas à corrente).

[]'s[/quote]

Legal, eu conheci o HATEOAS pelo seu livro de SOA, aliás parabéns pela obra;

E falando de SOA, já queria aproveitar para te perguntar Alexandre, se vc considera uma boa solução (à caminho do SOA) tranformar todos os serviços do Sistema(EJB) em EJB REST, inclusive os que o JSF consome, onde até os ManagedBeans passariam a consumir os serviços via REST também;

[/quote]

Na verdade, não. A grande vantagem de EJB em cima de um web service é que ele oferece um protocolo mais rápido, e encarar mudanças utilizando EJB é mais fácil do que essas mesmas mudanças em REST. Além do que, poderia trazer um grande risco de utilização inadequada, já que JAX-RS tem uma maneira de uso própria, que é diferente dos EJB’s.

O que poderia ser feito seria analisar quais desses EJB’s vale a pena expôr para outras linguagens e aí, sim, expô-los. Mas o sistema em JSF continuaria falando com a “faceta EJB”, digamos.

[]'s

Certo… obrigado pelas respostas Alexandre.

E vc comentou no livro que está escrevendo a continuação do mesmo.

Estamos aguardando!! :smiley:

[quote=TJvargas]Certo… obrigado pelas respostas Alexandre.

E vc comentou no livro que está escrevendo a continuação do mesmo.

Estamos aguardando!! :D[/quote]

Ih, ainda estou escrevendo um sobre REST. Vou começar com essa continuação depois que acabar o de REST. =)

[]'s