DTO - dúvida conceitual

wow… Voce consegue transformar ate o problema mais simples (fazer um conjunto de dados aparecer em outro ponto do sistema seja por cópia ou referência) numa questão digna de merecer a “melhor solução” que precisa de novos tipos, abstrações, frameworks, etc. :shock:

Detalhe, o objetivo inicial era claro no sentido de ser a solução mais simples…

mas voce pode justificar soluções complexas e apontar os perigos decorrente de uma solução mais simples, mas que tipo de bolha vc vive pra achar que isso é um campeonatinho de quem oferece a solução mais sofisticada? No mundo real o BOM programador precisa ser capaz de escolher quais os problemas que realmente valem a pena perder seu tempo. Talvez a empresa que o outro colega ai trabalha seja líder de vendas no mercado de frameworks de transferencia de objetos ou então se trata de um projeto opensource (que é hobby e não da precisa gerar dinheiro pro seu chefe), se não for este o caso…

[quote=mochuara][quote=sergiotaborda]
imagine a classe pessoa com nome (String) e data de nascimento (Date). Faça um map tipado para isso. :twisted:

O melhor que vc vai conseguir é Map<String, Object>

“Object” significa “não sei qual é o tipo”.
Existem alternativa que envolvem utilizar metadados que têm que estar presentes dos dois lados.
Funciona, mas dá muito trabalho e como já disse tem problemas.

[/quote]

wow… Voce consegue transformar ate o problema mais simples (fazer um conjunto de dados aparecer em outro ponto do sistema seja por cópia ou referência) numa questão digna de merecer a “melhor solução” que precisa de novos tipos, abstrações, frameworks, etc. :shock:

Detalhe, o objetivo inicial era claro no sentido de ser a solução mais simples…

mas voce pode justificar soluções complexas e apontar os perigos decorrente de uma solução mais simples, mas que tipo de bolha vc vive pra achar que isso é um campeonatinho de quem oferece a solução mais sofisticada? No mundo real o BOM programador precisa ser capaz de escolher quais os problemas que realmente valem a pena perder seu tempo. Talvez a empresa que o outro colega ai trabalha seja líder de vendas no mercado de frameworks de transferencia de objetos ou então se trata de um projeto opensource (que é hobby e não da precisa gerar dinheiro pro seu chefe), se não for este o caso…[/quote]

não sei em que dimensão vc vive, mas na minha dimensão HashDTO é um anti-pattern. Não só ele é , como eu já tive as mesmas ideias que vc está colocando e já as implementei e já vi que tem problemas práticos. Como já disse, funciona, mas tem problemas.
O principal problema é a tipagem fraca. O fato de não usar um bean o impede de interagir facilmente com outro frameworks como o hibernate e outros. HashDTO parece uma solução simples, mas não é. Estou lhe dizendo isto como um fato porque eu já usei. não se trata de procura a melhor solução, trata-se de - na minha dimensão - eu já ter experimentado essa solução e ter visto com os meus olhos que não é prática. A infra é simples, mas o uso é complexo.

A unica forma util de usar HashDTO é transformando de bean para map e vice versa usando o HDTO apenas na comunicação.
Mas vai dai isso obriga a ter a classe do bena original dos dois lados e isso significa que não precisa do HahsDTO pode simplesmente usar a classe do bean.

Na minha dimensão as pessoas têm experiencia com as coisas e as pessoas que não têm essa experiencia agradecem que as pessoas que a têm partilhem as suas conclusões. não só isso, como - na minha dimensão - existe a internet e existe centenas de pessoas contando suas experiencia. Na minha dimensão - que eu chamo de mundo real também - ser um bom programador não significa saber tomar decisões sobre design patterns e o problema dos objetos distribuídos não é simples.

[quote=sergiotaborda]
não sei em que dimensão vc vive, mas na minha dimensão HashDTO é um anti-pattern. Não só ele é , como eu já tive as mesmas ideias que vc está colocando e já as implementei e já vi que tem problemas práticos. Como já disse, funciona, mas tem problemas.
O principal problema é a tipagem fraca. O fato de não usar um bean o impede de interagir facilmente com outro frameworks como o hibernate e outros. HashDTO parece uma solução simples, mas não é. Estou lhe dizendo isto como um fato porque eu já usei. não se trata de procura a melhor solução, trata-se de - na minha dimensão - eu já ter experimentado essa solução e ter visto com os meus olhos que não é prática. A infra é simples, mas o uso é complexo.

A unica forma util de usar HashDTO é transformando de bean para map e vice versa usando o HDTO apenas na comunicação.
Mas vai dai isso obriga a ter a classe do bena original dos dois lados e isso significa que não precisa do HahsDTO pode simplesmente usar a classe do bean.

Na minha dimensão as pessoas têm experiencia com as coisas e as pessoas que não têm essa experiencia agradecem que as pessoas que a têm partilhem as suas conclusões. não só isso, como - na minha dimensão - existe a internet e existe centenas de pessoas contando suas experiencia. Na minha dimensão - que eu chamo de mundo real também - ser um bom programador não significa saber tomar decisões sobre design patterns e o problema dos objetos distribuídos não é simples. [/quote]

Acontece que -na dimensão do post que ressucitou o tópico- não se trata de sistema distribuido e nem foi mencionado que vai usar hibernate. Ainda assim vc continua sustentando o mesmo argumento? :shock:

[quote=mochuara]
Acontece que -na dimensão do post que ressucitou o tópico- não se trata de sistema distribuido e nem foi mencionado que vai usar hibernate. Ainda assim vc continua sustentando o mesmo argumento? :shock: [/quote]

Sim. Se estamos falando de um sistema local então nem ha porque falar em DTO para começo de conversa. Logo, usar HashDTO seria a exarcebação do erro.

Você pode estar confundindo com objeto de contexto (Context Object) em que o map funciona perfeitamente. Este tipo de objeto é passado e repassado várias vezes , mas tecnicamente ele não é um DTO. Exemplos classicos são o request, o response e o session da servlet api.

[quote=sergiotaborda][quote=mochuara]
Acontece que -na dimensão do post que ressucitou o tópico- não se trata de sistema distribuido e nem foi mencionado que vai usar hibernate. Ainda assim vc continua sustentando o mesmo argumento? :shock: [/quote]

Sim. Se estamos falando de um sistema local então nem ha porque falar em DTO para começo de conversa. Logo, usar HashDTO seria a exarcebação do erro. [/quote]

Pirou de vez? Quem falou de DTO, hashDTO, HBO… foi vc!!!

[quote=sergiotaborda]
Você pode estar confundindo com objeto de contexto (Context Object) em que o map funciona perfeitamente. Este tipo de objeto é passado e repassado várias vezes , mas tecnicamente ele não é um DTO. Exemplos classicos são o request, o response e o session da servlet api.[/quote]

Eu confundi? Bom, pelo menos vc teve um momento de lucidez finalmente, é por ai mesmo. Eu não chamaria de DTO tb, chamaria de… advinha, um map.

[quote=mochuara][quote=sergiotaborda][quote=mochuara]
Acontece que -na dimensão do post que ressucitou o tópico- não se trata de sistema distribuido e nem foi mencionado que vai usar hibernate. Ainda assim vc continua sustentando o mesmo argumento? :shock: [/quote]

Sim. Se estamos falando de um sistema local então nem ha porque falar em DTO para começo de conversa. Logo, usar HashDTO seria a exarcebação do erro. [/quote]

Pirou de vez? Quem falou de DTO, hashDTO, HBO… foi vc!!!
[/quote]

:?: :?: :?: :?: :shock:

Titulo do topico : “DTO - duvida conceitual”

Citação do André Fonseca que reiniciou o topico :"Lendo algumas referências, inclusive muitas apresentadas aqui, consigo entender o que é o DTO e quando usar. "

Eu falei em DTO porque esse é o tema do topico!

EoM

Então vc respondeu pra pessoa errada porque eu não falei de DTO, mas sim de usar um map.

[quote=sergiotaborda]Se estamos falando de um sistema local então nem ha porque falar em DTO para começo de conversa. Logo, usar HashDTO seria a exarcebação do erro.

Você pode estar confundindo com blablabla…[/quote]

A semântica de um map é completamente diferente de um DTO, porque não reconhece que esta viajando na maionese desde o início porque o sistema é local e vc continua falando em DTO, hashDTO (seja la que porra é essa).

oi

acho que talvez o motivo da confusão foi a forma de eu expressar a minha dúvida

o que eu queria saber é qual a melhor forma de se criar uma lista com o retorno de um result set de tal forma que seja fácil iterar nesta lista no meu cliente - camada que vai usar esta lista

o que se costuma fazer é criar um objeto burro com apenas estado e criar uma lista com estes objetos

talvez este saco de atributos tenha mesmo mais a ver com o outro VO que mencionei acima do que o DTO que é o antigo VO renomeado pela SUN, e que na verdade surgiu para resolver o problema de trafegar objetos em rede em sistemas distribuidos…

a minha dúvida teria mais a ver com: isso é considerado uma quebra do paradigma OO? isso é uma má pratica? afeta performance? teria uma forma mais customizavel de se fazer isso? ( para o caso dos atributos desses sacos de atributos mudarem??)

resumindo, acho que confundi mesmo o atual VO com o DTO…

[quote=André Fonseca]oi

acho que talvez o motivo da confusão foi a forma de eu expressar a minha dúvida

o que eu queria saber é qual a melhor forma de se criar uma lista com o retorno de um result set de tal forma que seja fácil iterar nesta lista no meu cliente - camada que vai usar esta lista

o que se costuma fazer é criar um objeto burro com apenas estado e criar uma lista com estes objetos

(…)
a minha dúvida teria mais a ver com: isso é considerado uma quebra do paradigma OO? isso é uma má pratica? afeta performance? teria uma forma mais customizavel de se fazer isso? ( para o caso dos atributos desses sacos de atributos mudarem??)

[/quote]

Vamos esclarecer a nomenclatura. Se você tem um sistema orientado a dados vc traduz linhas de banco em PropertyBags. Estes objetos são burros. (Veja que o proprio ResultSet é um ProeprtyBag neste sentido)
Se vc traduz cada linha num sistema orientado a entidades vc traduz para uma instância de uma entidade. Estas classes têm logicas além de get/set. por exemplo, logicas de estado num método “isActive()” que é true se o campo XTPO não é nulo, por exemplo.

Vc tem PropertyBags ou entidades ?
A entidades podem ser cross-layer. Podem. Não têm que ser.

Agora vc precisa passar uma coleção desses objetos para outra camada.

Nessa outra camada o objeto tem as mesmas propriedades ?

Na camada de apresentação é comum necessitar de mais dados do que aqueles que estão na entidade/bag original para controle da propria apresentação. Neste caso é licito implementar objetos especiais da camada. O Core JEE chama a isto ViewHelpers, mas seria mais como entidades da camada de apresentação. quando a entidade do dominio é cross-layer ela é usada tb como entidade da camada de apresentação. É comum carregar um list passar o jsp e usar um c:forEach para iterar e usar os proprios campos para ler e escrever os valores. Mas as vezes não funciona.

no struts 1 por exemplo, as actionforms são objetos populados da tela e para a tela. Vc tem que traduzir suas entidades de dominio para esses objetos. Esses objetos são “view entitys”.

Se vc usa PropertyBag no sistema , mais uma ou menos uma propriedade não muda nada, mas se usa entidades é bem provável que precise convertê-las para PropertyBag em algum ponto ( trasnferencia para outro nodo, persistencia, exportação/inportação , webservices e display, são as mais comuns). Sobretudo se esse ponto é na fronteira do sistema.

Não ha nenhuma quebra de OO se as responsabilidades forem bem entendidas e separadas. Na realidade vc usa isso todos os dias, vc só não presta atenção :slight_smile: ( O Hibernate transforma as entidades num objeto intermédio que é como um array de colunas com valores. Vc não vê, mas ele está usando essa mesma logica que vc está falando.

Sérgio,

Entendi do que foi dito que na verdade o meu sistema precisa de uma lista de Property Bags e não Entidades.

Agora, quanto ao fato desses objetos mudarem com o tempo? Qual seria uma forma que facilitaria a customização?

Por exemplo,

O meu objeto Pessoa mudou sua propriedade de

para

String primeiroNome; String sobreNome;

Como refletir estas mudanças em todas as camadas que utilizam listas deste objeto? Seria introspecção uma boa forma? (java beans) Você teria um exemplo de como fazer isso com um Map que fosse de fácil alteração depois?? (Supondo que eu não tenha propriedades tipadas)

[quote=André Fonseca]Sérgio,

Entendi do que foi dito que na verdade o meu sistema precisa de uma lista de Property Bags e não Entidades.

Agora, quanto ao fato desses objetos mudarem com o tempo? Qual seria uma forma que facilitaria a customização?

Por exemplo,

O meu objeto Pessoa mudou sua propriedade de

para

String primeiroNome; String sobreNome;

Como refletir estas mudanças em todas as camadas que utilizam listas deste objeto? Seria introspecção uma boa forma? (java beans) Você teria um exemplo de como fazer isso com um Map que fosse de fácil alteração depois?? (Supondo que eu não tenha propriedades tipadas)[/quote]

com map não dá para usar como vc quer. As keys dos maps não são interpretadas por nenhuma IDE como propriedades. Logo, vc teria que fazer esse refactoring na mão e ai vc se estrepa.
Ai vc usa beans com seus set/get e reflection. Existem bibliotecas que ajudam a fazer isso se vc não quiser fazer na mão.

Com isso vc ganha não só tipagem forte para cada campo mas tb facilidade de refactoring que é muito mais importante ainda.

Usar map para isso não é uma boa(esse era o ponto em relação ao HashDTO), vc vai se arrepender logo na primeira vez que precisar trocar o nome de algum campo.

[quote=André Fonseca]
Agora, quanto ao fato desses objetos mudarem com o tempo? Qual seria uma forma que facilitaria a customização?

Por exemplo,

O meu objeto Pessoa mudou sua propriedade de

para

String primeiroNome; String sobreNome;

Como refletir estas mudanças em todas as camadas que utilizam listas deste objeto? Seria introspecção uma boa forma? (java beans) Você teria um exemplo de como fazer isso com um Map que fosse de fácil alteração depois?? (Supondo que eu não tenha propriedades tipadas)[/quote]

Assumindo que vc preferiu estender um map ao invés de criar um wrapper, ficaria assim:

pessoa.remove(“nome”);
pessoa.put(“primeiroNome”, “André”);
pessoa.put(“sobreNome”, “Fonseca”);

Caso não queira fazer na mão pode passar o “trabalho” para um estagiário. Tudo que ele precisa fazer é ler o javadoc do hashmap.

algo q sempre tive duvida é: qual a diferença entre um DTO, TO e VO? pra mim são as mesmas coisa…

Isso é uma pergunta ou uma afirmação ?
Se for uma pergunta a resposta é: a diferença é historica.

Historicamente os nomes Value Object e Transfer Object significavam a mesma coisa. è um objeto “burro” serializável que permite passar dados entre nodos. Eram padrões do J2EE Core patterns

Ai veio o Martin Fowler e utilizou o nome Value Object para se referir a um outro tipo de padrão. Então o nome Value Object e VO passaram a significar isso, e ele criou o nome DTO para significar o que TO significava.

A segunda edição do core jee patterns aboliu o uso de VO no sentido antigo e deixo o nome Transfer Object (que é mais genérico que Data Transfer Object) para signifca o objeto burro serializável.

Ai para evitar confusão o temo DTO foi abandonado (embora significa o mesmo que TO) e apenas os termos Value Object - significando o padrão do Fowler e TO significando o padrão do core j2ee paterns ficaram.

Hoje em dia se vc se referir ao objeto burro serializável como “VO” vc estará indicando que não está atualizado e tudo o que deriva dai.