DTO - dúvida conceitual

73 respostas
R

Tava discutindo neste tópico9http://www.guj.com.br/posts/list/23408.java) sobre DTO´s, e fiquei curioso quanto o conceito.
O que caracterizaria um DTO, uma classe/objeto que seria transportado pelas camadas da aplicação, ou o simples retorno de um método também caracterizaria-se um DTO?
Por exemplo, numa aplicação web, para retornar os dados para uma view, eu executo minhas regras de negócio com meus objetos, e retorno do controller para a view somente uma Collection com as informações/atributos necessários para aquela view. Isso caracteriza um DTO?

73 Respostas

K

Rafael Nunes:
Tava discutindo neste tópico9http://www.guj.com.br/posts/list/23408.java) sobre DTO´s, e fiquei curioso quanto o conceito.
O que caracterizaria um DTO, uma classe/objeto que seria transportado pelas camadas da aplicação, ou o simples retorno de um método também caracterizaria-se um DTO?
Por exemplo, numa aplicação web, para retornar os dados para uma view, eu executo minhas regras de negócio com meus objetos, e retorno do controller para a view somente uma Collection com as informações/atributos necessários para aquela view. Isso caracteriza um DTO?

DTO nada mais seria que um VO.
Ou seja, uma classe com atributos privados que contém gets e sets para acessar os dados indiretamente.
A collection em si não seria um DTO, mas sim a classe utilizada dentro desta collection

Me corrijam se tiver engando!

J

Melhor que passar uma collection é passar um array de structs tipados.
ex:

class FuncionarioDTO
{
   public int codigo;
   public String nome;
   public String nomeDepartamento;
}

class FuncionarioService
{
   public FuncionarioDTO[] consultarFuncionarios()
   {
      //pode ser array, pois para passar para o client tem que desacoplar do server.
   }
}
R

DTO nada mais seria que um VO.
Ou seja, uma classe com atributos privados que contém gets e sets para acessar os dados indiretamente.
A collection em si não seria um DTO, mas sim a classe utilizada dentro desta collection

Na documentação não fala nada sobre getters/setters, diz somente qual a função:
Use a Value Object to encapsulate the business data. A single method call is used to send and retrieve the Value Object. When the client requests the enterprise bean for the business data, the enterprise bean can construct the Value Object, populate it with its attribute values, and pass it by value to the client.
Minha dúvida em específico(e bem besta pelo visto) é se um simples método no meu controller retornando uma Collection, caracterizaria um DTO/VO

EU discordo, desta forma você teria de ter um VO/DTO pra cada objeto, retornando um array de cada um deles, o que eu estou tentando entender é a forma de retornar os dados para view de uma melhor forma, não fazer gambiarra, mas passar para ela somente o necessário(leia-se não ter de passar 50 objetos com 50 atributos cada e usar só 5 atributos de cada objeto)

J

Sim , neste caso você só passará os atributos necessários.
Não é uma cambiarra.
É o que é proposto.
Mas dessa maneira o problema é esse que voce falou.
Eu teria que ter não um DTO para cada objeto, mas sim para cada requisição.
Tem a vantagem de ficar tudo “tipadinho”.
Mas a desvantagem de ter muitas classes para fazer muito pouco.

Pelo que vi os conselhos do pessoal, passar coisas muito genericas não fica legal.

Do jeito que você quer teria que ser uma collection de hashMaps.

_

Qual o problema de retornar objetos normais, só que apenas com os atributos que você vai usar populados?

T

Rafael Nunes

DTO, que quer dizer Data Transfer Object, quer dizer Objeto de tranferência de dados. Mas, para bons programadores, isso não quer dizer exatamente objeto de transferência de dados. Você deve utilizar DTO para resolver o seguinte tipo de problema:

Por exemplo, suponha que vc deverá fazer vários acessos remotos seguidos para realizar uma tranzação distribuída. Então vc primeiro chama um método, ele acessa o servidor remoto, vc chama outro método, ele acessa um servidor remoto, e daí vc faz isso de novo.

O tempo que se gasta fazendo todos estes acessos tem como consequencia uma perda consideravel no tempo de execução da aplicação.

Então, ao invés de ficar transportando uma renca de objetos um de cada vez, vc coloca todos os objetos (ou os dados dele) em uma objeto só, e passa para o servidor. Então vc perde menos tempo com o transporte de dados.

Ao invés de acessar um servidor 3 vezes, vc acessou 1 só. É para isso quer serve um DTO.

Agora Rafael, use somente nestes casos, e nada mais. Não saia inventando DTO pelo seus sitema. O pessoal agui chama esse treco de gambiarra, e realmente é!

Resumo. Use DTO quando vocÊ precisa fazer muitos acessos remotos. Desta forma ao invés de realizar N conexões, vc realizara apenas uma.

Abraços!
Thiago Senna

R

Suponha que durante um processo eu utilize 30 objetos, não precisam estar necessariamente com todos os atributos preenchidos, mas o necessário para relizar a tarefa. Depois de realizada, eu preciso retornar para a view dos trinta objetos apenas 5 atributos que estão ‘espalhados’ entre eles. Como retornar isso sem ser por uma Collection que reuniria o conteúdo dos 5 atributos?(Aí é que está a dúvida, isso seria um DTO?)
E baseando-me na tua sugestão, eu teria de duplicar meus objetos, setando somente os atributos que eu necessito, ou configurar o que eu não preciso como nulo. Creio que fica um tanto inverossímil retornar cinco objetos quando eu necessito somente de cinco atributos.

R

Agora Rafael, use somente nestes casos, e nada mais. Não saia inventando DTO pelo seus sitema. O pessoal agui chama esse treco de gambiarra, e realmente é!

Resumo. Use DTO quando vocÊ precisa fazer muitos acessos remotos. Desta forma ao invés de realizar N conexões, vc realizara apenas uma.

Creio que não estou me fazendo entender. Agradeço pela resposta, porém minha dúvida não é quando usar, isso eu entendi. Minha dúvida é o que caracteriza um DTO.

Sendo sucinto e conciso:
Retornar um Collection com atributos dos meus objetos de domínio para a view é um DTO?

J

Pelo que eu entendi uma DTO seria nada mais nada menos que um struct que é passado entre tiers.
um struct seria uma classe sem métodos com apenas atributos a serem populados
ex:

class Funcionario
{
   private int codigo;
   private String nome;
   private Departamento departamento;
   // getters e setters
}

class Departamento
{ 
   private int codigo;
   private String nome;
}

class ConsultaFuncionarioDTO
{
   public int codigoFuncionario;
   public int codigoDepartamento;
   public String nomeFuncionario;
   public String nomeDepartamento;
}

class FuncionarioService
{
    public ConsultaFuncionarioDTO[] consultarFuncionario()
    {
      Collection funcionarios = Funcionario.consultar();
      ConsultaFuncionarioDTO[]  consultaDTO = new ConsultaFuncionarioDTO[funcionarios.size()]  
      
       Iterator i = funcionarios.iterator();
       for (int index = 0; i.hasNext(); i++)
       {
           Funcionario func = (Funcionario) i.next();
           consultaDTO[index] = new ConsultaFuncionarioDTO();

           consultaDTO.codigoFuncionario = funcionario.getCodigo();
           consultaDTO.codigoDepartamento = funcionario.getDepartamento().getCodigo();
           consultaDTO.nomeFuncionario = funcionario.getNome();
           consultaDTO.nomeDepartamento = funcionario.getDepartamento().getNome();
 
        }
 
        return consultaDTO;
      }
}

Pode parecer tosco, mas se seguirmos ao pé da letra o que é DTO é isso.
Agora se é necessário usar ou não ?
Eu prefiro a ideia do LIPE.
Passe o objeto.
O problema se o objeto for bem modelado ele terá métodos que vão além de simples accessors e interagem na lógica de negócios.
Nestes casos é melhor usar objetos burros para passar dados.

P

Oi.

Diz o tio Fowler:

Ou seja: não importa se tem get, se tem set, se tem coleção, sem coleção, é uma gambiarra por si só. A característica do padrão é empacotar o máximo possível (necessário) para amenizar chamadas RPC.

Leiam mais aqui.

J

Mas o que você acha de implementar um tipo de DTO para cada requisição/retorno ?
Teriamos muitas classes “inuteis”, mas ficaria tudo bem tipado.
Uma DTO generica deixaria a arquitetura muito pobre.

R

Putz, desisto.
Ou eu sou muito prego e não consegui entender a mensagem subentendida.
Ou eu não estou sabendo me expressar.

_

Você falou que tem dúvida sobre o que caracteriza um DTO. O Shoes respondeu citando o PoEAA.

T

Hummm… naum… acredito que não!

DTO é uma gambiarra, que tem um monte de atributo e gets e sets. Vc vai usar ele quando vc tem que chamar vários métodos remotos. Mas ao invés de chamar uma renca de metodo remoto, vc cria um método que recebe o DTO e retira os dados de dentro dele, e finalmente recompões os objetos de negócio!

Como vvc tá implementando não importa. Vc pode até retornar uma collection de DTO. As formas de implementações são várias.

Entenda DTO como uma gambiarra que se faz necessário para transmitir uma coleação de informação que podem ser referentes a mais de um objeto de negócio, que quando chega no seu destino ele é utilizado para reconstruir todos os dados dos objetos de negócio.

Abraços!
Thiago

J

como o Shoes falou antes qualquer estrutura que vc use para transportar dados entre as camadas da sua app é um dto.

so não acho que seja uma gambiarra, todo mundo fala isso, alguns so pq viram no forum.
ele tem sua utilidade em cenarios especificos.
se vc tem sua aplicação distribuida, vai precisar de uma estrutura para transportar os dados.

agora, se existe uma melhor maneira de utilizalos ae ja não sei…

[]'s

T

Mas pelo q entendi o Shoes não criticou sua utilidade, o DTO tem utilidade mas ainda assim é uma gambiarra…
Por exemplo, o mapeamento Objeto-Relacional é extremamente funcional e útil, talvez não exista solução melhor, mas ainda assim é uma gambiarra.

C

O grande ponto a se grifar eh o “se voce tem uma aplicacao distribuida…”: DTOs sao um design pattern, Local-DTOs sao um anti-pattern. :wink:

F

Ai vem uma outra grande pergunta. Quantos projetos sao realmente distribuidos que justifiquem o uso de DTO?

]['s

P

Não precisa ser um sistema monstro, mas você está certo no que acho que tentou dizer: 99% dos posts no GUJ sobre isso são sistemas que não precisam de DTOs.

T

Me lembro como se fosse hoje quando tava começando o meu projeto de final de curso e usei a seguinte estrutura

view --> controle --> façade --> negocio --> DTO --> DAO

Fiz diagrama de classes e tudo!!! Achei que eu estava arrasando por que haviam 8 patterns em meu sistema que não tinha tem 10 classes de negócio direito!

Daí eu mostrei para alguns professores, e todos eles me parabenizaram!!
Aff… Fiquei tão orgolhoso!!! :oops:

Abraços!
Thiago

T

Antes que me perguntem pq fiz isso… eu digo!

Tinha acabado de ler alguns dos capítulos do livro Core J2ee Patterns!
Imaginem um cabeção e mala que nem eu no 3º ano da faculdade diante de um livro desses! Ele chega a pensar que está no paraíso!

Abraços!
Thiago

J

Mas o DTO não deveria estar entra o controle e o facade ?

view --> controle --> DTO --> façade --> negocio --> DAO

F

pcalcado:
fabgp2001:

Ai vem uma outra grande pergunta. Quantos projetos sao realmente distribuidos que justifiquem o uso de DTO?

Não repcisa ser um sistema mosntro, mas você está cerot no que acho que tentou dizer: 99% dos posts no GUJ sorbe isso são sistemas que não precisam de DTOs.

Isso, mas digo mais, acho que mais de 90% dos sistemas desenvolvidos em Java nao sao distribuidos.

F

jprogrammer:
Mas o DTO não deveria estar entra o controle e o facade ?

view --> controle --> DTO --> façade --> negocio --> DAO

Porque o DTO esta em uma camada se ele so fica zanzando no sistema?
Existem sistemas onde o DTO é criado na View e vai sendo enviado até o DAO, nao entendo o porque dessa distribuicao demostrada ai.

]['s

P

fabgp2001:

Isso, mas digo mais, acho que mais de 90% dos sistemas desenvolvidos em Java nao sao distribuidos.

Eu também. Mais até, bem mais.

Hoje em dia eu trabalho com cluster e clientes remotos, e mesmo assim em uns dois projetos apenas. De resto, nada justificaria um DTO para aplicações web como as que eu já fiz tantas por aí.

R

Pelo o que eu li um DTO serve para diminuir a sobrecarga na rede devido a chamadas de métodos remotos, certo? É tipo “zipar” os dados e mandar de uma vez só, em vez de um a um, certo?

E o pessoal confunde e usa DTO para simplesmente para acessar banco de dados, certo? Eu mesmo confundo (ou confundia, sei lá) um pouco, achando que aqueles beans burros que representam as entidades do BD eram DTOs.

Certo???

P

Na mosca!

A cosia qeu me dá mis medo quando respondendo alguém aqui ou em alguma lsita é:

Onde eles arrumam tanta criatividade?

T

Jprogrammer… obrigado por me lembrar… a estrutura que eu coloquei tava errada!

Na verdade eu tinha feito assim (Podem acreditar… é sério)

view --> DTO --> controle --> DTO --> façade --> negocio --> DTO --> DAO

Abraços!

F

Nao só isso, acho que a maior confusao é com as siglas. DTO, VO, Pojo, Java Beans pra muitos isso é tudo igual e sabemos que isso nao é verdade.
Exemplo, quando o Hibernate diz que precisa de POJO pra persistir os objetos, muitos acham que sao obrigados a usar DTO por isso.

]['s

T

Fabgp:
Nao só isso, acho que a maior confusao é com as siglas. DTO, VO, Pojo, Java Beans pra muitos isso é tudo igual e sabemos que isso nao é verdade.
Exemplo, quando o Hibernate diz que precisa de POJO pra persistir os objetos, muitos acham que sao obrigados a usar DTO por isso.

Não é somente isso!
Na verdade, temos o costume de pensar que o ideal é contruir um sistema super flexível há mudanças! E muitos pensam que software flexível é sistema enfestado de patterns!
Daí, a falta de experiência fazem com que nós interpretemos estes patterns (DTO) desta maneira.

O problema é que todo mundo quer sistema flexível. O lógico parece ser que um sistema burocrático é o mais ideal para as mudanças, enquanto metodologias ágeis felizmente traz uma outra abordagem, no qual sistemas flexíveis em mudanças são programas com código simples e com bém testado! (resumidamente)

Abraços!

_

Só para encher o saco, o Hibernate não precisa hehe só o construtor default é necessário, infelizmente.

E, só para alfinetar:
“Pessoas inventam porcentagens para ganhar credibilidade. 87% das pessoas sabem disso.” - Homer Simpson
:XD:

P

Pra mim e (e?) tudo a mesma coisa… leio vc precisa de um (cole aqui uma das sopa de letrinhas supracitada) e no final das contas vejo um JavaBean. Não e pra pensar que e tudo a mesma coisa?

Depois de ler esse topico entendi o que e um DTO (eu acho) e que na verdade nao preciso dele pra p* [piiii] nenhuma.

Agora:
VO = DTO?
Pojo = JavaBean?

Deus me livre!

T

Pra mim e (e?) tudo a mesma coisa… leio vc precisa de um (cole aqui uma das sopa de letrinhas supracitada) e no final das contas vejo um JavaBean. Não e pra pensar que e tudo a mesma coisa?

Depois de ler esse topico entendi o que e um DTO (eu acho) e que na verdade nao preciso dele pra p* [piiii] nenhuma.

Agora:
VO = DTO?
Pojo = JavaBean?

Deus me livre!

Sim… VO = TO = VO != boas práticas em sistemas não distribuídos!

POJO != Java Bean…

quando se fala de java bean me lembra mais a especicificação de se usar os metodos getAlgumaCoisa, setAlgumaCoisa, isBoolean e por ai vai…

POJO, por sua vez é mais flexível. Pojo nada mais é do que um objeto java simples, sem frescura, sem vaidade, sem batom e sem botox! Se vc vai usar o nome dos métodos igual aos do java bean nele, vc pode fazer isso tranquilamento, assim como muitos fazem!

P

Mais que isso, JavaBeans é uma especificação de componentes bem adiantadinha pra sua época, mas que não funfou. O que sobrou dela na maiorida das vezes são frameworks que fazem reflection beaseados em set/Get/Construtor vazio e um ou outro uso de BeanInfo.

Na verdade, essa convenção existe mesmo em C++. Não sei se foi influência de Java (sacrilégio!!!), mas que tem tem.

P

http://fragmental.com.br/wiki/index.php?title=Evitando_VOs_e_BOs

S

Felipe creio que isso não seja uma boa maneira…o bom é ter o seu objeto sempre completo fica meio estranho voce passar um objeto em que voce só tem um dado, se for assim é preferível retornar um array de string…sei lá o o tipo dos seus dados mas nunca o objeto pela metade…

A

Felipe creio que isso não seja uma boa maneira…o bom é ter o seu objeto sempre completo fica meio estranho voce passar um objeto em que voce só tem um dado, se for assim é preferível retornar um array de string…sei lá o o tipo dos seus dados mas nunca o objeto pela metade…

hã ?

R

Importante:

DTO não é um javabeans com getters e setters.
DTO não é o mesmo que um Value Object.
DTO não é um anti-padrão, nem o Fowler falou que DTO é um anti-padrão.

Recomendo:
(Re)Ler com atenção o que o Shoes, CV e Fowler (http://martinfowler.com/bliki/AnemicDomainModel.html) escreveram.

E, muito importante…
Padrões não são receitas!

R

E digo mais… a resposta do Rafael é mesmo muito boa!


Agora, faço a seguinte pergunta: Eu devo julgar os padrões pela intenção ou pela “implementação” (isto é, a descrição do Padrão no GoF, “obsessivo” por heranças)?

Rafael Ferreira:

Vou deixar o John Vlissides responder essa:
?It seems you can?t overemphasize that a pattern?s Structure diagram is just an example, not a specification. It portrays the implementation we see most often. As such the Structure diagram will probably have a lot in common with your own implementation, but differences are inevitable and actually desirable. At very least you will rename the participants as appropriate for your domain. Vary the implementation trade-offs, and your implementation might start looking a lot different from the Structure diagram.
As for whether one is following the pattern or not, who cares? The pattern is a means to an end, not an end itself. Following it in any strict sense is immaterial. If the pattern solves your problem directly, that?s great; if you have to bend it a bit, that?s great too. Even if the pattern merely inspires you toward an altogether different solution, it has still proven useful. The only potential problem here lies in the documentation phase, when you?re describing your solution in terms of patterns. You don?t want to mislead someone with irrelevant patterns. If you identify a set of classes as adhering to a pattern, make sure they fulfill the pattern?s intent. If the connection is tenuous, don?t mention the pattern; otherwise you?re sure to confuse more than clarify. ?

S

Essa teria graça se não fosse triste.
Padrões não são receitas de bolo, realmente. Não são “10 passos para a classe maravilhosa”. Isso é verdade.
Mas daí a menosprezar os padrões … peraí …
Padrões são coisas série. Ou vc segue ou não segue. Mesmo que vc se sinta inspirado, se vc não segue o padrão à risca,
o que vc obtem não é uma implementação do padrão. O detalhes é saber o que é o “padrão à risca” e isso sim é uma coisas metafisica. Mas isso apenas porque os livros de padrões são catálogos e não teses sobre axiomática.
Vc pode definir os padrões sob a forma de teoremas derivados “matemáticamente” da axiomática de OO. Mas isso seria um texto
chato que 95% das pessoas passaria longe. Com a ideia de que o padrão é uma receita (embora não seja realmente, sim) essas 95% das pessoas pelo menos vão aceitar a ideia.

O que é triste é ter que ler que prototype , mediator e façade são tipos semelhantes de padrões. Essa doeu.
Claro que quem defende que padrões são felxiveis, não são sérios e são meros “guias” dá-se ao luxo de dizer uma coisa dessas.
Para quem acha que padrões são colorários dos axiomas de OO isso equivale a dizer que a operação de soma, divisão e conjugação são tipos semelhantes de operação…

R

Existe necessidade de ser agressivo quando se posta no forum???
Juro que não entendi a agressividade gratuita. :shock:

De qualquer forma, seu argumento vai de encontro à definição de padrão. Se padrões são soluções recorrentes, identificado em situações diferentes… ninguém estava seguindo nada à risca. Nas palavras do fowler:

“One of the interesting things here is that a singular solution can often lead to a recurrent pattern. This usually crops up when you see two different singular solutions which look completely different on the surface, yet have a deeper similarity”
.

Padrões são sérios, e são coisas importantes. Mas é preciso entendê-los e não vê-los como receitas.
Um ótimo exemplo disso é o DTO. O padrão fala do problema de usar vários getters e setters entre sistemas distribuídos. Isso seria muito ruim… Ao invés disso, sugere-se enviar um objeto que encapsule todas essas informações. Ponto.

O padrão não dita que você não pode colocar código de validação, comportamento, etc nos DTOs.

Outro excelente exemplo é o padrão strategy. Sugiro que as pessoas leiam a descrição do padrão e comparem com a idéia de Interface do Java. Observe que no C/C++ e no Smalltalk não existe Interface… O que você acham? O conjunto List + implementações (ArrayList, LinkedList, etc) não implementa o padrão Strategy? Pattern é isso, uma solução recorrente (um conjunto de melhores práticas) para problemas recorrentes.

F

Aos participantes gostaria de indicar este livro:

REFATORAÇAO PARA PADROES
Autor: KERIEVSKY, JOSHUA
Editora: ARTMED
Assunto: INFORMATICA-PROGRAMAÇAO

O autor aconcelha a ler o livro com a presença de outro livro do Mr. Martin Fowler REFACTORING IMPROVING THE DESIGN OF EXISTING CODE pois ele faz várias referencias sobre este livro.

P.S. O livro é em ingles mas o traduzido está com a qualidade aceitavel, vale a pena dar uma olhada.

Ahhh…já ia esquecendo neste livro não fala de DTO rsrsrsrsr.

flw

R

rs…
engraçadinho…

Ahhh…já ia esquecendo neste livro não fala de python. hahahahah!

S

rodrigousp:
Existe necessidade de ser agressivo quando se posta no forum???
Juro que não entendi a agressividade gratuita. :shock:

Juro que não entendi onde está a agressividade gratuita.

Nas minhas próprias palavras:
“Padrões são colorários dos axiomas de OO”

Eles não aparecem do nada como o Fowler expressa , eles está lá sempre.
Se vc seguir as regras OO ( os axiomas , como SoC, IoC , encapsulamento, etc…) vc tem um código enxuto . Mesmo que vc não saiba os nomes dos padrões que acabou de usar, eles estão lá.
Quando vc identifica uma solução isso não acontece porque vc está notou uma coincidencia, e sim porque vc está vendo as regras funcionarem. Elas funcionam sempre da mesma forma e por isso as “coincidencias” são recorrentes.

Pois não. Mas regras mais importantes ditam, como o SoC.
O que vc está dizendo é que se eu pegar um pojo da vida o fizer serializable e colocar um monte de codigo de validação, colocar o construtor privado , colocar get/set paras os atributos, colocar um método estático para retornar o objeto que eu crio dando clone de um atributo estático privado e final na classe eu estarei usando : Prototype (clone copy), Factory-Method (método de criação), TO (serializable) e Bean (get/set).
Não. Vc está fazendo apenas uma salada de frutinhas e pior, violando o SoC.
Em suma, se viola o SoC o seu codigo não pode ser considerado bom, muito menos um padrão.

Interfaces são constutos uteis ao padrão strategy, mas não são a “implementação do padrão strategy” isso é absurdo. Strategy pode ser feito com herança normal se não existissem interfaces.
ArrayLisr , etc… sim são estratégias de List que por sua vez é estratégia de Collection. Isso sim. Mas nunca “interface” per se será um padrão.

Como os texto que citou falam : padrão é algo que não existe na linguagem. É algo que vc faz com a linguagem.

Padrões não são conjuntos de melhores práticas, são o resultado direto do seguimento coerente dos principios de OO. Quando vc aplica os principios de OO a um problema vc obtem um resultado. Se aplicar de novo os mesmos princípios vc obtem o mesmo resultado. A aplicação dos principios é complexa, por isso vc pula essa fase. Dai quand vc tem um problema vc tem a solução. Mas ela não aparece magicamente.

Um exemplo, a lei de pitagoras para a relação entre os catetos e a hipotenusa de um triangulo retangulo pode ser usada diretamente sem ter que a deduzir a todo o momento. O mesmo que a as leis de newton.
Ou seja, se vc tem um problema vc aplica o que já sabe e obtem um resultado. Vc não perde tempo deduzindo a solução a partir de principios básicos cada vez que tem um problema. Da mesma forma vc não deduz a solução para um problema de OO a cada vez que precisa, vc faz isso as primeiras vezes e depois vc já sabe a solução e aplica. Vc cataloga as soluções para fácil uso e pronto.
As solução advem dos principios. Os padrões são atalhos. Dado um problema o padrão dá a solução. Mas o padrão contêm em si todo o processo de aplicação dos princípios da OO.

Padrão não são receitas de bolo, mas são mais que guias: são corolários. Ou seja, não é possivel, para o mesmo problema encontrar outra solução diferente. Se fosse guias ou receitas poderiam ser encontradas outras formas.

O que temos diferente são as implementações. Ai sim, existem muitas variantes. Mas o padrão não inclui a implementação, por isso a variedade de implementações não afeta em nada a realidade de que o padrão é univocamente definido pelo problema e pela aplicação dos axiomas de OO.

[/quote]

R

Esse assunto é muito jóia…

Eu enfatizo que o conceito do padrão é mais importante que a estrutura. Veja:

ok

A validação pode ficar nos setters, correto!? Se os getter e setters só atribuirem/devolverem os valores da propriedades seriam só idiossincrasia para acessar a propriedade internas do objeto.

Huh(vamos ver…)

ok

Ops…

ok! Se é interessante clonar seu objeto, não tem nada de errado com isso. Ainda não vi a motivação mas pode ser que faça sentido. Sei lá, vai ver que você esteja fazendo um joguindo de carros e o servidor disponibiliza novos modelos de carros. Cada cliente recebe os modelos de carro e permite que usuário faça modelos personalizados a partir desses. (Serializável e clonável). Nesse caso o modelo segue o Prototype.

Aí não. Eu falei que o conceito do padrão é importante, não a estrutura. Usar um método para criar outro não faz um “factory method”. Existe uma motivação para o Factory Method e não existe nenhuma motivação na saladinha.

Pode ser que sim… desde que a motivação coincida com o padrão. No exemplo do jogo do carrinho seria uma estupidez os clientes serem informados de propriedade por propriedade de cada modelo. É mais inteligente o servidor enviar todo o objeto. Esse é um exemplo do uso do DTO.

Isso também não. Para começar que um Javabeans é um componente de software, não um padrão. E existe uma especificação que dita quando uma classe Java pode ser chamada de Javabeans… De forma simplificada:

Ainda no exemplo dos carrinhos, o código não precisa ser um padrão. Mas, alguns padrões podem ser encontrados na resolução desse problema.

Concordo plenamente!!!

Sobre a parte de corolários, etc… acho que não podemos fazer tal afirmação. A demonstração rigorosa que um padrão deriva matematicamente de “axiomas de OO” não deve ser alguma coisa fácil, talvez nem seja possível… Seria realmente incrível provar que dado um contexto(limitações) e um problema (necessidades) não seria possível encontrar um modelo melhor do que o modelo de um certo padrão. Mas por enquanto isso é uma especulação (conjectura) não um teorema.

S

Vc passou longe do ponto. O ponto era :misturar um monte de pedaços de cada padrão não significa usar o padrão.
Tlv vc defenda que o conceito do padrão é mais importante que a implementação. Tudo bem. Mas não era isso que o blog que vc apontou como justificativa defendia. Ha uma enorme confusão de padrões lá. Era disso que estava falando.

Eu não falei em javabean eu falei em bean. Sim, JavaBean é um componente e uma especifiação, mas bean é algo mais simples.
Todos os javabeans são beans, mas o contrário não é verdade.

Dificil ? … hummm… não importa se é difícil, importa que é possível. O ponto é que padrão tlv sejam encontrados empiricamente, mas eles têm uma base teórica. Sem ela, não existe padrão. É no máxima uma boa prática e no pior caso uma gambiarra.
Mas nem é tão dificil assim:
O padrão Composite, por exemplo, nasce diretamente do conceito de composição que é uma forma de relacionar objetos.
O padrão Composite não é qualquer tipo de composição. É um tipo especial onde o composto é da mesma classe do componente. è isso que marca a diferença e o padrão. Não é difícil entender que composição é uma relação de objetos diretamente derivada do próprio conceito de objeto e portanto o Composite é um padrão derivado matematicamente de axiomas OO ( a existência de objetos é o primeiro axioma)

R

Desculpa ai (1)… Eu estava só provando o que eu havia falado antes: que o padrão DTO NÃO dita um Objeto anêmico.

Desculpa ai (2) … Na literatura que eu conhecia, beans e Javabeans eram sinônimos. E um Javabeansprecisava ter construtor sem parâmetros público. Então apesar dos getters e setters, não poderíamos chamar aquele exemplo de Javabeans.

Eu não diria que esta essa é a demonstração mais formal que conheço. Na minha opinião seria preciso tomar o padrão composite, como apresentado pelo Gof e sua “Estrutura”: Component, Composite and Leaf. Então, seria preciso demonstrar que aplicando os aximos do OO teríamos essas entidades e teríamos que tomar o cuidado para mostrar como cada uma dessas partes atuam não deixando dúvidas se Component pode ou não ter
métodos de manipulação de listas, se um autorelacionamento pode ou não desempenhar o papel de composição, etc.

Eu concordo plenamente que existe uma base teórica importante sobre os padrões de projeto.
Mas volto a enfatizar que o conceito é mais importante que a estrutura.

S

Não foi intenção ser formal. Embora “formal” seja relativo aqui.

Ora ai é que está. Porque como paresentado pelo GoF ? Eles são algum tipo de deuses ? E aliás as ideias deles são para C++
Se é verdade que a base toerica é mais importante que a implementação não importa que seja em C++, mas vai dai, também não importa que seja do GoF.

não. A implementação é irrelevante. métodos de manipulação de listas são irrelevantes. Podem ser adicionados se necessário Por exemplo, se a composição for imutável esses métodos não podem existir. Mas isso é detalhe de implementação.
Auto-relacionamento é um tpo de relacionamento e portanto auto-relacionamento pode ser composição e pode ser visto como um corolário do padrão. Esse tipo de coisas não entram no padrão.

O padrão é definido como a composição (operação entre objetos) recursiva. Ou seja, um objeto da classe X pode ser composto por objetos da classe X. É só isso. (Em uml um tipo - classe, interface - tem relação de composição consigo mesmo. )

Se o objeto composto é adicionado a si mesmo é uma auto-composição ( um ciclo fechado) Se o objeto não é composto por mais nenhum objeto então ele é diretamente um leaf. Ou seja, o leaf advém da propria regra e não é necessário presupor a sua existencia à partida.

Se o objeto leaf é especializado isso não é mais um problema do padrão Composite. Isso é a implementação de outro padrão: Strategy. Normalmente isso é legal ( Swign por exemplo) mas não é uma condição sin qua non para ter composite.

Ou seja, o ponto, é que não é tão complexo assim derivar as coisas, mas a principio isso não é feito no dia-a-dia, dai a necessidade de catálogos. Tlv os catálogos não enfatizem o suficiente a relação que os padrões têm com as regras de OO. Isso é uma pena, porque leva muita gente a achar que padrões são coisas apenas empíricas.

É que achando que são apenas empíricas sentem-se no direito das dobrar à sua situação, descaracterizando os principios de OO e portanto o padrão.

O exemplo classico: o cara cria um objeto com variável static private e um método para retorna essa instancia. Ai ele diz que isso é a implementação de singleton. Esse é o problema. Não é a implementação de singleton pela simples razão que não cumpre as regras do padrão em particular : um único objeto da classe deve existir a qualquer momento.
( se o construtor é publico, por exemplo, outros objetos podem ser criados.)

A

Ressucitando um tópico do passado ...

Lendo algumas referências, inclusive muitas apresentadas aqui, consigo entender o que é o DTO e quando usar.

Agora a minha dúvida é bem pontual.

Suponha que eu tenha um método de acesso ao banco que me retorna um result set, eu preciso que este método retorne para o cliente - a camada que vai usá-lo, seja view ou business sei lá - uma lista formatada que seja de fácil iteração.

O que eu quero dizer com isso? Quando eu faço

List list = new ArrayList();
while (rs.next()) {
  Pessoa p = new Pessoa();
  p.setNome(rs.getString("nome"));
  p.setIdade(rs.getInt("idade"));

  list.add(p);
}

Fica fácil no meu cliente saber iterar na lista e fazer o que for preciso.

Mas isso seria ruim? Pois a classe Pessoa muito provavelmente só teria sentido em ter os seus atributos e os seus gets e sets.

Uma sugestão - primeira página do tópico - seria passar o que o programmer chamou de um array de structs tipados.

Eu já tinha visto esta alternativa antes, mas isso pode ser ruim pois eu toda classe que precisasse eu teria que ter uma estrutura dessas.

Uma outra alternativa seria você criar um hashmap e depois um iterator pra facilitar as coisas. Mas será que o esforço vale a pena?

Achei um link interessante que trata da mesma situação

http://consultingblogs.emc.com/jaddy/archive/2009/10/01/how-not-to-use-dtos-in-domain-driven-architectures.aspx

Na sessão Our solution ele diz

From coding perspective, we used beanutils and a bit of reflection to achieve cloning of objects.

Seria essa uma boa idéia? Não seria um tiro de canhão para matar uma mosca?? :roll:

O que vocês costumam fazer? Ou usam o VO Pessoa mesmo??

A

a minha duvida tem a ver com a frase acima tb, no caso que eu coloquei não tenho uma aplicação distribuida …

F

Como que é sua aplicação?

É client x server?

flws

A

sim, entretanto as camadas que eu mencionei rodam no mesmo ambiente. eu posso até estar fazendo acesso a um banco de dados remoto, mas não há necessiade de trafegar estes objetos pela rede…

S
André Fonseca:
Ressucitando um tópico do passado ...

Lendo algumas referências, inclusive muitas apresentadas aqui, consigo entender o que é o DTO e quando usar.

Agora a minha dúvida é bem pontual.

Suponha que eu tenha um método de acesso ao banco que me retorna um result set, eu preciso que este método retorne para o cliente - a camada que vai usá-lo, seja view ou business sei lá - uma lista formatada que seja de fácil iteração.

O que eu quero dizer com isso? Quando eu faço

List list = new ArrayList();
while (rs.next()) {
  Pessoa p = new Pessoa();
  p.setNome(rs.getString("nome"));
  p.setIdade(rs.getInt("idade"));

  list.add(p);
}

Fica fácil no meu cliente saber iterar na lista e fazer o que for preciso.

Mas isso seria ruim? Pois a classe Pessoa muito provavelmente só teria sentido em ter os seus atributos e os seus gets e sets.

Uma sugestão - primeira página do tópico - seria passar o que o programmer chamou de um array de structs tipados.

Eu já tinha visto esta alternativa antes, mas isso pode ser ruim pois eu toda classe que precisasse eu teria que ter uma estrutura dessas.

Uma outra alternativa seria você criar um hashmap e depois um iterator pra facilitar as coisas. Mas será que o esforço vale a pena?

Achei um link interessante que trata da mesma situação

http://consultingblogs.emc.com/jaddy/archive/2009/10/01/how-not-to-use-dtos-in-domain-driven-architectures.aspx

Na sessão Our solution ele diz

From coding perspective, we used beanutils and a bit of reflection to achieve cloning of objects.

Seria essa uma boa idéia? Não seria um tiro de canhão para matar uma mosca?? :roll:

O que vocês costumam fazer? Ou usam o VO Pessoa mesmo??

Se a sua aplicação é orientada ao dominio obrigatoriamente vc terá uma List<Entidade> e portanto vc é obrigado a criar objetos dessa entidade.
Contudo, vc não é obrigado a criar esses objetos à mão, nem a criá-los junto à leitura do resultSet.

Para não os criar à mão vc usa reflection. Todos os frameworks fazem isso. Conceptualmente isso não passa de uma forma de injeção. Vc injeta um monte de outros objetos na classe da entidade.
O fato deles serem dados da entidade é um detalhe.

Vc não precisa criar o list e populá-lo com a leitura do resultset; Vc pode usar o padrão Fastlane Reader. Este padrão poupa objetos na memoria e apenas traduz o rs para o objeto quando necessário.
Nestes casos o uso de List ou outro tipo de collection não é aconcelhável a menos que vc tenha codigo legado escrito dessa forma.

Você pode abstrair esse codigo até ter algo que funciona para qualquer classe. Basicamente vc estará fazendo o que o Hibernate faz. Mas para isso dar certo vc precisa de algum tipo de metadados.
Sem metadados o unico jeito e´fazer na mão. Reflection oferece muitos metadados, mas podem ñ ser suficientes. Por exemplo, não contém nome de tabelas e colunas...

Este tipo de trabalho não se caracteriza como o uso de DTO. O uso de DTO implica duas coisas : orientação a dados (data) e distribuição (transfer). Usar entidades descaractetiza o uso de dados e o fato de estarem na mesma jvm descaracteriza transfer ( todos os DTO são serializable, entidades não precisam ser).

Cuidado com a confusão entre DTO e VO. Tem muita coisa sobre isso no guj é questão de procurar, mas resumindo : VO não são DTO e DTO não são VO.

F

sergiotaborda:
Este tipo de trabalho não se caracteriza como o uso de DTO. O uso de DTO implica duas coisas : orientação a dados (data) e distribuição (transfer). Usar entidades descaractetiza o uso de dados e o fato de estarem na mesma jvm descaracteriza transfer ( todos os DTO são serializable, entidades não precisam ser).

Cuidado com a confusão entre DTO e VO. Tem muita coisa sobre isso no guj é questão de procurar, mas resumindo : VO não são DTO e DTO não são VO.

Sendo assim (client x server), também concordo com que o Sergio disse.

flws

M

Achei interessante (porque reflete a situação do Java) é que a opção mais simples que é do hashmap é considerado um “esforço”. :slight_smile:

S

Existe uma derivação do DTO chamada HashDTO que usa um map para a transferencia. O problema é que isso não é fortemente tipado e leva a um monte de outros problemas.

M

Existe uma derivação do DTO chamada HashDTO que usa um map para a transferencia. O problema é que isso não é fortemente tipado e leva a um monte de outros problemas.

Ele é fortemente tipado, é um hashmap. :slight_smile:

Não é um tipo específico da sua aplicação, e nem vejo motivo para tal, visto que é apenas para trafegar objetos entre modulos distintos. Não ter que manter código de infraestrutura é uma vantagem IMO, principalmente numa linguagem que impõe tanta cerimônia na definição de tipos.

S

Existe uma derivação do DTO chamada HashDTO que usa um map para a transferencia. O problema é que isso não é fortemente tipado e leva a um monte de outros problemas.

Ele é fortemente tipado, é um hashmap. :slight_smile:

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.


Não é um tipo específico da sua aplicação, e nem vejo motivo para tal, visto que é apenas para trafegar objetos entre modulos distintos. Não ter que manter código de infraestrutura é uma vantagem IMO, principalmente numa linguagem que impõe tanta cerimônia na definição de tipos.

Na ideia é boa, na prática não é util.

A

oi

não estou me referindo a este value object mas sim ao value object criado pela sun e que depois foi renomeado para DTO.

Vou procurar estudar um pouco sobre o que falou, principalmente sobre esse Fastlane Reader.

Sobre as outras sugestões a minha dúvida fica para quando eu não tenho os frameworks ou então o uso dos metadados fica dificil…

Na verdade nem sei se seria mesmo o VO, mas o que eu queria saber era uma forma de empacotar os dados de uma forma que fosse facil de iterar depois, algo semelhante a uma struct de dados do C… A minha dúvida é saber se é ruim usar esta classe pessoa com seus gets e sets só para agrupar o retorno do result set ou se tem uma forma melhor de fazer isso…

Tanto em termos de performance como também de manutenção, já que fica difícil quando precisarmos um dia de alterar esta classe ou bean ou sei la se o atributo nome mudar para primeiroNome e ultimoNome…

Neste caso concordo que usar reflection ou metadados vai facilitar bastante…

abs

M

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…

S

mochuara:
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.

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…

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.

M

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.

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:

S

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:

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.

M

sergiotaborda:
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:

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.

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

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.

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.

S

mochuara:
sergiotaborda:
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:

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.

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

:?: :?: :?: :?: :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

M

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

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…

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).

A

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…

S

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??)

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.

A

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)

S

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)

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.

M

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)

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.

L

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

S

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.

Criado 28 de abril de 2005
Ultima resposta 8 de dez. de 2009
Respostas 73
Participantes 20