O que usar no lugar de VOs?

Aqui sempre vejo muita gente "metendo o pau" em VOs (também chamados de TOs e DTOs). Não use isso, isso é uma gambiarra e blablabla.

Pois bem, vejo muita gente metendo o pau, mas pouca gente propondo uma solução. Que tipo de arquitetura VO-less vocês usam? Onde os dados são armazenados em memória? As classes de negócio tem estados ou não?

Suponha que você tenha um sistema que contém uma classe CellRendererGenerico<? extends VO> e uma classe CellRendererCliente extends CellRendererGenerico<ClienteVO>. Que tipo de refatoramento você faria nas classes CellRendererGenerico e CellRendererCliente?

Princípio da OO: manter dados e lógica no mesmo objeto.

Vc nao precisa necessariamente programar Orientado a Objetos. Frameworks como o BC4J da Oracle, e o JCompany, usam objetos que só representam estado. E ja ouvi argumentos como o de ‘performance’ ( … a, ta bom, vc vai instanciar 10000 objetos prum relatorio, tendo estado em todos eles?.. ), a favor de usar VO.

Mas sei lá… vai de analisar e ver qual sua necessidade.

Já o pessoal do Design-Domain Drive
Fala do uso de VO… …

tb gostaria de saber … pq o pessoal não gosta?

:?:

[quote=sandeco]Já o pessoal do Design-Domain Drive
Fala do uso de VO… …

tb gostaria de saber … pq o pessoal não gosta?

:?:

[/quote]
O VO que o pessoal de Domain-Driven Design fala não é o mesmo que o Data Transfer Object (DTO, nome atual do antigo VO catalogado pela Sun). O Value Object de DDD é um objeto que armazena valores, que não possui identidade ou ciclo de vida e deve ser imutável. Já o Value Object da Sun é um objeto que possui apenas dados, como se fossem os structs de C ou os records de Pascal. Seu uso deve ser empregado em ambientes onde serializar um objeto pode ser custoso (um ambiente distribuído, por exemplo).

Não confunda ValueObject [Fowler] com DTO[CoreJ2EEPatterns]. ValueObject é um conceito de dominio.

Atualmente trabalhamos com POJOS. Não temos problemas em criar um CellRenderer<PedidoVenda>. Este pedido venda pode ser um @Entity, é persistente, pode ter métodos de negócio e não é um DTO.

ok, vamos manter dados e lógica no mesmo objeto.
Nossa classe “QualquercoisaVO” agora vai se chamar “Qualquercoisa” e então terá uma série de métodos.

Mas com certeza teremos que trafegar o objeto “qualquercoisa” pelas camadas da nossa aplicação.

Como fica isso quanto a performance/serialização desse objeto ?

[quote=andersonlfl]ok, vamos manter dados e lógica no mesmo objeto.
Nossa classe “QualquercoisaVO” agora vai se chamar “Qualquercoisa” e então terá uma série de métodos.

Mas com certeza teremos que trafegar o objeto “qualquercoisa” pelas camadas da nossa aplicação.

Como fica isso quanto a performance/serialização desse objeto ?[/quote]

Não só uma serie de métodos mas também uma série de associações de negócio. O “Qualquer coisa” trafega sim pelas camadas da nossa aplicação sem problemas pois é um POJO (não confuda POJO com DTO). Esse objeto é serializado e trafegado da mesma forma que ocorre com o DTO, pois a serialização é com relação ao estado.

As camadas são lógicas e não fisicas. Não tem problema manusear uma Entidade na camada de view, como exemplo. De qualquer forma, não é qualquer aplicação que precisa serializar objetos. Uma aplicação web comum não usa isso. Não distribua seus objetos.

Esse foi o principal engano que todo mundo causou com os DTOs. Eles foram feitos para diminuir o overhead do tráfego de rede, no tráfegos de objetos pelas camadas de rede(tiers/física) da sua aplicação, e não nas camadas da aplicação(layers/lógica).

Tem razão, afinal o que trafega pelas camadas da aplicação é na verdade um endereço de memória e não um objeto em si.

E quanto ao Hibernate?
Tenho um “Qualquercoisa.hbm” representando um "xxx.Model.Qualquercoisa"
Esse cara guarda os estados que serão populados na base. Aqui meu objeto será serializado certo ? Se meu model “Qualquercoisa” agora tem uma série de métodos e associações de negócios, a performance/serialização disso não será prejudicada ?

Tem razão, afinal o que trafega pelas camadas da aplicação é na verdade um endereço de memória e não um objeto em si.

E quanto ao Hibernate?
Tenho um “Qualquercoisa.hbm” representando um "xxx.Model.Qualquercoisa"
Esse cara guarda os estados que serão populados na base. Aqui meu objeto será serializado certo ? Se meu model “Qualquercoisa” agora tem uma série de métodos e associações de negócios, a performance/serialização
disso não será prejudicada ?[/quote]

Pelo que eu sei, não é assim que a banda toca. Já pensou se você tivesse 1000 objetos da sua classe QualquerCoisa instanciados, sendo que QualquerCoisa declara 4 métodos e esses métodos também fossem “instanciados”, ou seja, se houvesse 4000 métodos em memória?
Não é assim que acontece, os objetos possuem apenas seu respectivo estado. O código dos métodos está em algum lugar da memória mas é compartilhado por todas as intâncias. Logo, serialização não tem relação alguma com os métodos, métodos não são serializados, apenas dados (estado).

Alguém por favor me corrija se falei besteira :slight_smile:

Certo. O que ocorre é que nos primeiros 4 ou 8 bytes de memória alocado a um objeto existe uma referência à classe deste (que pode ser obtida pelo método getClass()). Após estes primeiros bytes, seguem os demais campos pertencentes ao objeto. Primeiro os da superclasses e depois os das subclasses, e na ordem em que são declarados. Os métodos e construtores são referenciados no objeto Class, que mantém uma estrutura de dados com ponteiros para os métodos e construtores. Na inicialização de Class estes ponteiros são inicializados com cópias dos ponteiros dos métodos da superclasse, alguns destes são sobrescritos por outros métodos (e aí ocorre a sobrescrita) e são adicionados mais alguns ponteiros para os métodos novos.

Mas, voltando ao foco do tópico:

O VO (ou TO, ou DTO) contém getters e setters burros para todos os seus campos, o que não provê um encapsulamento verdadeiro (dá quase na mesma que ter todos os atributos públicos). Como objeto de negócio, apenas métodos de mais alto nível acessam os campos, provendo um encapsulamento verdadeiro, o que dispensa a necessidade da maior parte dos getters e setters.

Mas, e quando você utiliza algum tipo de framework, tal como Hibernate ou algo baseado em Reflection para construir ou alterar instâncias dinamicamente? Como você evita de ter que colocar getters e setters para todos os campos deixando o encapsulamento fraco e ao mesmo tempo permitindo que o tal framework faça o seu serviço direito?

[quote=victorwss][quote=cassio]

[/quote]

Certo. O que ocorre é que nos primeiros 4 ou 8 bytes de memória alocado a um objeto existe uma referência à classe deste (que pode ser obtida pelo método getClass()). Após estes primeiros bytes, seguem os demais campos pertencentes ao objeto. Primeiro os da superclasses e depois os das subclasses, e na ordem em que são declarados. Os métodos e construtores são referenciados no objeto Class, que mantém uma estrutura de dados com ponteiros para os métodos e construtores. Na inicialização de Class estes ponteiros são inicializados com cópias dos ponteiros dos métodos da superclasse, alguns destes são sobrescritos por outros métodos (e aí ocorre a sobrescrita) e são adicionados mais alguns ponteiros para os métodos novos.

Mas, voltando ao foco do tópico:

O VO (ou TO, ou DTO) contém getters e setters burros para todos os seus campos, o que não provê um encapsulamento verdadeiro (dá quase na mesma que ter todos os atributos públicos). Como objeto de negócio, apenas métodos de mais alto nível acessam os campos, provendo um encapsulamento verdadeiro, o que dispensa a necessidade da maior parte dos getters e setters.

Mas, e quando você utiliza algum tipo de framework, tal como Hibernate ou algo baseado em Reflection para construir ou alterar instâncias dinamicamente? Como você evita de ter que colocar getters e setters para todos os campos deixando o encapsulamento fraco e ao mesmo tempo permitindo que o tal framework faça o seu serviço direito?[/quote]

No Hibernate você tem opção de colocar as annotations direto sobre os atributos ou nos getters (não sei no caso de XML, aprendi Hibernate já usando annotations e não gosto de XML…). No caso de colocar nos atributos, mesmo que esses atributos sejam privados e não existam os respectivos getters e/ou setters, o Hibernate acessa os campos através de reflection e seta/lê os valores sem problemas.

“Pelo que eu sei, não é assim que a banda toca. Já pensou se você tivesse 1000 objetos da sua classe QualquerCoisa instanciados, sendo que QualquerCoisa declara 4 métodos e esses métodos também fossem “instanciados”, ou seja, se houvesse 4000 métodos em memória?
Não é assim que acontece, os objetos possuem apenas seu respectivo estado. O código dos métodos está em algum lugar da memória mas é compartilhado por todas as intâncias. Logo, serialização não tem relação alguma com os métodos, métodos não são serializados, apenas dados (estado).”

Alguém mais me confirma isso?

Esse foi o principal engano que todo mundo causou com os DTOs. Eles foram feitos para diminuir o overhead do tráfego de rede, no tráfegos de objetos pelas camadas de rede(tiers/física) da sua aplicação, e não nas camadas da aplicação(layers/lógica).

[/quote]

Perfeito!!! DTO é para trafegar beans entre TIERS, nao entre LAYERS! Entre layers é perfeitamente aceitavel que layers diferentes acessem suas entidades de dominio!

[quote=fabiocsi]“Pelo que eu sei, não é assim que a banda toca. Já pensou se você tivesse 1000 objetos da sua classe QualquerCoisa instanciados, sendo que QualquerCoisa declara 4 métodos e esses métodos também fossem “instanciados”, ou seja, se houvesse 4000 métodos em memória?
Não é assim que acontece, os objetos possuem apenas seu respectivo estado. O código dos métodos está em algum lugar da memória mas é compartilhado por todas as intâncias. Logo, serialização não tem relação alguma com os métodos, métodos não são serializados, apenas dados (estado).”

Alguém mais me confirma isso?[/quote]

Sim, é isso.

:smiley:
http://forum.java.sun.com/thread.jspa?threadID=5142354&tstart=105
:stuck_out_tongue:

Ok, se o princípio é manter os dados e sua lógica juntos, o que faríamos então se o tal objeto é o grande objeto principal da aplicação? Como evitar que este se torne um Chuck Norris Object :lol: de 3000 linhas, mapeador ou agregador de dados vindos de 30 colunas de tabelas diferentes?

Não estaríamos sobrecarregando o papel dele?

Se existir algo como “grande objeto principal da aplicação”, em primeiro lugar, já é sinal de que seu problema é outro.

É, se realmente existir um ‘Grande Objeto Principal’ na sua aplicação, tipo um Canivete Suiço, é sinal que tem algo bem bizarro com o design de teu projeto.

olá amigos
abaixo topico longo e confuso, igual a minha cabeça quando penso nisso…

Sabe as vezes eu acho esse negocio de nomes em java um saco e passo a não levar a serio mais padrões de projeto…

Hoje usamos POJO (Plain Old Java Objects) Anotados…
quer dizer porque Martin Fowler em Setembro de 2000 usou a expressão para falar de objetos simples em java…
passamos a usar POJO… legal…

Pegunta 1:
Alguem sabe porque ele não usou JavaBean??? uma vez que JavaBean e uma coisa e Enterprise JavaBean e outra coisa completamente diferente…

Pergunta 2:
POJO não seria um JavaBean??? Uma vez que utilizamos os mesmos padrões de nomenclatura?

Pergunta 3:
Já DTO utilizamos para transferencia entre camadas, mais DTO’s não seriam POJO’s ? POJOS’s não passam por camadas? hoje com EJB3 e JPA representam entidades, Isso me lembra VO ???

Pergunta 4:
VO não seria um POJO?

Entity Beans esses sim não são POJO’s, ele falou de POJO para diferenciar um Objeto Java em relação a um Entity Bean não e isso?

honestamente? acho que esses caras (cada um investam um nome para tudo) na verdade estão protegendo os seus empregos e egos “investando” padrões que na verdade já existiam…

Porque já que temos que cultuar as pequenas diferenças de utilização,teremos que começar chamar POJO’s Anotados de “Plain New Annotated Java Objects”.

o cv a um tempo atraz fez um topico questionando o porque ninguem entendia o porque VO’s eram uma má ideia… na epoca o topico tomou outro caminho…

me sinto muito burro de não entender porque são uma má ideia…

porque quando penso como fazer um sistema distribuido sem passar as “entidades” para o cliente popular e me passar para persistir no meu humilde banco de dados, fila MQ enfim… sem VO’s, TO’s, DTO’ ou “raio que o parta O”

Alguem pode me ajudar a entender?