VOs/DTOs são POJOs, também. Só que não contém lógica de negócio. E a idéia defendida é justamente usar os POJOs para modelar a lógica de negócios - o que afasta a necessidade de VOs.
No meu entendimento a questão toda é que objetos Java não são meros empacotadores de dados (o que equivaleria ao typedef struct da linguagem C).
Empacotadores de dados descaracterizam a idéia da orientação a objetos. Até mesmo as classes Wrapper do Java, apesar do nome, não são meros empacotadores, uma vez que oferecem métodos para facilitar operações com os tipos.
Assim, a pergunta que faz sentido para mim é: qual é a finalidade de agrupar um monte de atributos com getters e setters em um objeto sem atribuir funcionalidades (métodos com lógica de negócio) ao mesmo? Que eu creio que seja o cerne da questão.
Ainda mais considerando que na maioria desses casos nem mesmo a hierarquia chega a ser bem utilizada, acabando por descartar de vez a orientação a objetos.
O que uma Pessoa (classe Pessoa) tem e faz? nome, idade, sexo, etc… ela anda, pula, come e, extendendo a classe Pedreiro, trabalha em construções.
O que um VO tem e faz? Tem um monte de atributos e não faz nada, é cego, surdo, mudo e tetraplégico, e a menos que alguém na aplicação o carregue nas costas, serve só como peso morto a ser carregado, mesmo…
Assim, com certeza há design patterns mais modernos e inteligentes que colocam a funcionalidade, a regra de negócio, no objeto, junto com os seus atributos, em uma modelagem que faz uma utilização ampla e rica do paradigma OO, utilizando interfaces para proporcionar loose coupling.
Por exemplo o Spring com a IoC: veja que na IoC, por exemplo, o objeto não é mais só um peso a ser carregado… ele passa a ter inteligência… ele pode inclusive ter a flexibilidade de executar mais de uma lógica dependendo da injeção de dependência realizada…
Esta lógica de negócios a que vc se refere significa que o VO seria uma classe para um amontoado de dados sem ligação direta entre si? Tipo... no POJO, vc armazena todos os dados de uma tabela, no VO, vc armazena os atributos que vc necessita trafegar pela aplicação?
É, 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.[/quote]
Não é um canivete suíço, é um objeto que é o foco principal da aplicação.
Seria a classe ‘Pessoa’ num sistema de gerenciamento de pessoas, que visa agregar o máximo de informação sobre ela.
A classe ‘Venda’ de um grande sistema de vendas.
A ‘molécula’ em um sistema de simulação fisioquímica muito detalhado.
Basicamente aquelas classes típicas que podem juntar muita informação nelas. E mais típico ainda, você é o programador a a decisão da linda arquitetura não teve a sua participação/foi decidida há muito tempo.
A questão é, como agregar muitas funções de dados e lógica e manter a complexidade baixa?
É disso que a própria orientação a objetos se trata…
Desenvolvedores ortodoxos estabelecem até uma marca… acima de X linhas de código tá na hora de criar outra classe, porque a atual já está ficando desnecessariamente grande e complexa…
Não. Orientação a objetos se trata de colocar a lógica próxima dos dados, em pequenos “sistemas” que interagem entre si (objetos). Modelando a lógica em POJOs, é justamente isso que fazemos (e, notar, ninguém está defendendo que existam “getters” para todos os atributos - como escreveu o Kent Beck, deve-se expor mínimo possível de dados através de getters - quando há necessidade de expor muitos dados, sinal de que a lógica está longe deles e deve ser movida)
VOs vão contra os princípios da orientação a objeto. Foram uma solução para problemas criados por uma tecnologia que já passou.
Tendo seu domínio (“lógica”) modelado em POJOs, qual o problema de fazê-los transitar pela aplicação?
VOs/DTOs são POJOs, também. Só que não contém lógica de negócio. E a idéia defendida é justamente usar os POJOs para modelar a lógica de negócios - o que afasta a necessidade de VOs.
[/quote]
Esta lógica de negócios a que vc se refere significa que o VO seria uma classe para um amontoado de dados sem ligação direta entre si? Tipo... no POJO, vc armazena todos os dados de uma tabela, no VO, vc armazena os atributos que vc necessita trafegar pela aplicação?
valew,
Rodrigo.[/quote]
Eu acho que a “idéia” pelo o que eu entendi é outra, é na verdade não fazer do POJO apenas um amontoado de getters/setters com atributos privados, mas também ter métodos de negócio/regra de negócio , como na classe Pessoa, ter um método andar(), dormir() e comer() por exemplo…estou certo? Agora deixa ver se eu entendi, uma prática comum que eu vejo por ai é o pessoal usando a classe de domínio usada pelo hibernate por exemplo e encapsulando ela até um determinado layer da aplicação e daquele layer pra cima usar um outro objeto com a mesma representatividade pra tratar a lógica da apresentação e outras coisitas mas… isso sim é ruim e o certo seria eu usar a própria classe de domínio entre os layers e se o meu negócio necessitasse criar métodos para deixar ele mais “inteligente”, acertei?
[quote=bzanchet]POJO não necessariamente é um JavaBean.
[/quote]
Sim e fato…
Como, como faço o mapeamento objeto relacional? vou ter que ter um parser para passar meus POJO’s com seus atributos de acordo com o negocio para os meus DTO’s que são “POJOS anotados” ??? isso e pratico?
uma frase que na pratica e bonita só pra não dizer nada…
Se meu sistema for distribuido (pelo amor de Deus, sem entrar no merido de precisa ou não) vamos assumir que sim, ele é, e sim ele precisar ser ok? e ai? como meu cliente vai acessar ? atraves de objetos simples na chamada da façade?
ou vou distribuir ou meu ClienteVO, TO, DTO, XPTO ???
Não quero discutir se preciso ou não de distribuir meu sistema, estou questionando se não estamos fazendo marketing demais com nomes de objetos…
na pratica…
POJO = Qualquer objeto java.
VO, TO, DTO etc etc etc = Objetos que representam dominios de negocio (uma vez que as tabelas do banco representam no negocio)
POJO não e padrão de projeto e um simples nome “ponposo” e Martin Fowler falou e tudo mundo fica igual umas maritacas falandom (força de expressão apenas)
o que eu estou tentando dizer e que as vezes criamos um monte de sopa de letras que não tem muita diferença entre elas…
não acha que nós que trabalhamos com java fazemos isso? ou não? esses padrões são uteis, esses nomes são uteis e eu sou maluco(a chance de eu ser maluco e grande)…
Ai que eu volto a perguntar… porque VO’s são uma má ideia?
Eu trabalhei em um sistema que permitia fazer lançamentos… (não vou entrar em detalhes porque tem sigilo).
Nesse sistema, o coração eram os lançamentos.
Fizeram uma classe BLancamento com mais de 6000 linhas de código. TODOS os lançamentos se resumiam em chamar o método tratar() da classe BLancamento, passando pra ele um VLancamento.
Esse VLancamento era um VO gigantesco, com muitos atributos, e o método tratar() fazia milhares de IFs, chamando milhares de outros métodos que faziam milhares de outros IFs dentro da própria classe BLancamento.
O pessoal perdeu a oportunidade de bolar uma bela arquitetura, criando um lançamento básico abstrato e extendendo ele para créditos e débitos, extendendo os créditos e débitos para cheques, saques, etc, etc… e cada objeto desses, sendo um objeto “de verdade” (não só um saco de atributos) poderia ter a lógica adequada para tratar o seu próprio caso.
E os lançamentos mais específicos poderiam herdar lógica dos lançamentos mais gerais…
Cada classe poderia ficar pequena, fácil de compreender mesmo por quem não conhecesse a aplicação, caracterizando uma manutenção simples e rápida, uma escalabilidade eficiente…
É possível perceber o quanto uma arquitetura boa pode facilitar a vida de todo mundo envolvido no projeto?
Classes boas não são classes grandes e difíceis cheias de códigos que ninguém entende. Muito pelo contrário: classes boas são as que até um iniciante entende facilmente.
Só que pra desenvolver um sistema complexo com classes tão simples que até um iniciante entenda, é preciso ter muita experiência com arquitetura, uma arquitetura rica possibilita uma modularidade e um baixo acoplamento suficientes para que cada classe realize com eficiência apenas o mínimo necessário.
Quem está falando de mapeamento objeto-relacional? Isso é oooutra história.
[quote=edpipole]como meu cliente vai acessar ? atraves de objetos simples na chamada da façade?
public void incluirCliente(Integer codigo, String nome, String sobreNome, String endereço, String[] telefones) ....
[/quote]
Tu sabes o que é sistema distribuído, mesmo? Acho que não estamos falando a mesma língua.
Qualquer, não. Qualquer old java object.
Ei, peraí. Se as tabelas do banco representam o negócio, pra que objetos, em primeiro lugar?
São uma má idéia porque afastam a lógica dos dados - quando, ao usar OO, estamos justamente tentando aproximar as duas coisas!
Em termos musicais, o tema da 9ª sinfonia de Beethoven é uma das coisas mais simples que existem. Notas fáceis, ritmo descomplicado… e é uma das obras mais conhecidas e aclamadas no mundo todo desde que foi composta.
Mas foi preciso um Beethoven para mostrar a grandeza de uma coisa simples… e ele só o fez após ficar surdo.
Ele só o fez quando deixou de ouvir a música com os ouvidos e passou a ouvi-la com a alma…
Mas só quem ama aquilo que estuda chega nesse ponto…
E para isso é preciso transpôr, às vezes, a correria prática do cotidiano dos projetos…
Quantas vezes somos incapazes de resolver um problema no trabalho, algum algoritmo, e depois em casa, embaixo do chuveiro, relaxados, de repente temos uma idéia que resolve o problema?
Bom, o ser humano ainda usa menos de 10% da sua capacidade cerebral durante toda a sua vida, a maioria não chega a 6%…
E é tão fácil a gente se julgar conhecedor de alguma coisa… quando isso mesmo nos impede de crescer mais…
Hehehe, deixa eu parar com esse momento filosófico antes que alguém tenha uma reação alérgica…
Falei pro Fox que eu ia ser insultado… mais vamos lá…
Também acho que não e 8, 80 na verdade e isso que estou tentando explicar, porque para mim sistemas grandes apenas com POJOS de negocio com os atributos ficam uma zona a longo prazo…
bzanchet, tudo bem…
vamos assumir que eu seja esse idiota que vc esta tentando dizer que eu sou…
Por favor parece simples demais pra você, me explica como eu faço um sistema usando apenas POJOs de negocio (Business Objects) com os atributos necessarios para cada BO dispensando os VOs dessa forma…
1 -) eu vou ter que fazer um parser de objetos para minha camada de persistencia… se não como? porque minhas entidades no banco refetem sim o meu negocio… isso e simples? facíl de manter?
2- ) O relacionamento entre as entidades sera apenas na persistencia?
3-) Como o mapeamento objeto relacional pode ser “outra coisa” se meu negocio tem que integir com ele o tempo todo?
estou pensando no todo…
Algum caso de sucesso? sem VOs e derivados? ou isso e apenas teoria? eu acho dificil manter parsers para os DTO`s do BO em diante… eu diria custoso para equipe…
nos projetos que eu tenho feito arquetura nos ultimos 3 anos sempre usei VOs, ou TOs ou DTO`s de ponta a ponta… sem parsers, pois sempre que tentei usar dava um trabalho danado por pouca recompensa…
Me ensina isso também… tabelas não representam o negocio?
Quando eu olho um banco eu vejo o negocio do cliente, uma pizzaria, tem a tabela de pedidos, de entregas, estoque essas coisas… não e isso?
Mais você concorda eu que vou ter que fazer um parser para popular os objetos do meu mapa relacional?
se sim, esse parser não e um saco de fazer em um sistema enorme?
além das interfaces o que eu passo para meu querido cliente remoto? caso eu tenho um? essa solução de unir negocio e dados e viavel para distribuir? não? sim? porque?
Orientação a Objetos tem décadas e até agora nada tomou seu lugar nod esenvlvimento de aplicações então esse ‘longo prazo’ é estranho
Não. Qualquer framework moderno (Hibernate/JPA, Btais, TopLink…) suporta o uso de objetos simples, não de DTOs. Na verdade estes frameworks encorajam o uso de objetos de negócio no lugar de objetos burros.
Não entendi essa pergunta
Mapeamento Objet-Relacional não faz parte da Camada de negócios, faz parte da Camada de Persistência. Objetos de negócio interaem entre si quando é preciso persistir algo ou buscar uma informação no banco isso é delegado à Camada de Persistência.
A grande maioria dos projetos utilizando Sping (desde a primeira versão), Hibernate, JPA ou coisa parecida seguem este modelo. EJB 3.0 é exatemnte sobre simplificar o modelo e conseguir criar objetos de negócio de verdade, sem DTOs.
Não existe a necessidade de parser.
[quote=edpipole][quote=bzanchet]
Ei, peraí. Se as tabelas do banco representam o negócio, pra que objetos, em primeiro lugar?
[/quote]
Me ensina isso também… tabelas não representam o negocio?
Quando eu olho um banco eu vejo o negocio do cliente, uma pizzaria, tem a tabela de pedidos, de entregas, estoque essas coisas… não e isso?
[/quote]
Num sistema orientado a objetos o que representa o negócio é seu modelo de objetos não seu modelo de dados. Na maioria das vezes o modelo de dados vai servir apenas para persistir os objetos.
Ah, acho que agora entendi o parser. isso não é um parser, é apenas um objeto que az mapeamento entre conceitos diferentes e existe um adrão muito difundido para isso: DAO, ou seu ‘pai’ genérico Data Mapper.
Depende do que você quer que eu cliente remoto faça. Se você possuir interfaces de granularidade baixa pode passar os próprio objetos serializados e azer chamadas remotas, se não pode utilizar o DTO: ele foi feito para isso.
eu sei que quem busca as coisas do BD e a camada de persistencia, mais que tipo de objeto ela vai me trazer? não seria um objeto simples? que representa uma tabela e seus relacionamentos?
quando eu pegar essa objeto simples não vou tratar seus dados na minha camada de negocio?
e disso que estamos falando não e mesmo?
Me ensina isso também… tabelas não representam o negocio?
Quando eu olho um banco eu vejo o negocio do cliente, uma pizzaria, tem a tabela de pedidos, de entregas, estoque essas coisas… não e isso?
[/quote]
Num sistema orientado a objetos o que representa o negócio é seu modelo de objetos
não seu modelo de dados.
Na maioria das vezes o modelo de dados vai servir apenas para persistir os objetos.
[/quote]
O banco ainda e relacional por isso fazemos o Mapeamento Objeto Relacional, mais o banco tambem representa o negocio
segundo o conceito dele, quando vou para meu sistama ai os meus objetos passam a representar segundo o seu conceito…
Sim acho que você entendeu, Data Mapper… isso mesmo…
O meu ponto nisso tudo e quando e custoso mapear as entidades do banco para objetos simples, depois mapear os objetos simples
para meus Objetos de negocio que foram desenvolvidos sem nem tomar conhecimento do banco de dados, na hora de persistir isso e um
saco ficar passando valor de um objeto para outro, o custo gerencial, garantir que o meu clienteBO tenha os mesmos atributos
que meu Objeto de banco para depois persistir isso tudo, nomes de campos e etc…
fizemos um projeto grande assim um tempo atraz, 20 desenvolvedores, desenvolvendo sem tomar conhecimento do banco, trabalhando apenas com
o Objeto de negocio, enfim… quando tinhamos que pegar algo no banco, tinhamos que acessar o DAO pegar o Objeto que vinha mapeado,
depois setar os atributos na minha BO e usar, para persistir tinhamos que pegar os valores que estamos trabalhando setar
nos Objetos de Mapeamento do banco e depois persistir…
era muito custoso…
você concorda com isso?
eu prefiro pegar o Objeto do banco o usalo ponta e ponta, fica mais simples de trabalhar com a informação…
o que vocês acham? entenderam o que eu fiz dizer?
Depende do que você quer que eu cliente remoto faça.
Se você possuir interfaces de granularidade baixa pode passar os
próprio objetos serializados e azer chamadas remotas, se não pode utilizar o DTO: ele foi feito para isso.[/quote]
[quote=edpipole]O meu ponto nisso tudo e quando e custoso mapear as entidades do banco para objetos simples, depois mapear os objetos simples
para meus Objetos de negocio que foram desenvolvidos sem nem tomar conhecimento do banco de dados, na hora de persistir isso e um
saco ficar passando valor de um objeto para outro, o custo gerencial, garantir que o meu clienteBO tenha os mesmos atributos
que meu Objeto de banco para depois persistir isso tudo, nomes de campos e etc…[/quote]
Não! Quando defendemos a modelagem da lógica de negócios em POJOs, é justamente isto que estamos evitando. São seus objetos Cliente, Pizza, Mozzarella, Calabresa, que vão deixar de ser “burros” e vão passar a ter lógica (junto aos dados). E que podem ser persistidos para o banco quando necessário - sem “parser” nem “clienteBO”.
[quote=bzanchet][quote=edpipole]O meu ponto nisso tudo e quando e custoso mapear as entidades do banco para objetos simples, depois mapear os objetos simples
para meus Objetos de negocio que foram desenvolvidos sem nem tomar conhecimento do banco de dados, na hora de persistir isso e um
saco ficar passando valor de um objeto para outro, o custo gerencial, garantir que o meu clienteBO tenha os mesmos atributos
que meu Objeto de banco para depois persistir isso tudo, nomes de campos e etc…[/quote]
Não! Quando defendemos a modelagem da lógica de negócios em POJOs, é justamente isto que estamos evitando. São seus objetos Cliente, Pizza, Mozzarella, Calabresa, que vão deixar de ser “burros” e vão passar a ter lógica (junto aos dados). E que podem ser persistidos para o banco quando necessário - sem “parser” nem “clienteBO”.
[/quote]
hum… legal… mais ai caso tenha um cliente remoto, tenho que seguir o conselho do pcalcado e minhas interfaces irão receber objetos simples serializados? mesmo porque não vou poder passar esse POJO uma vez que ele tem a regra de negocio junto certo?
Bom, nessa situação, como ja foi dito antes, o uso de VO/TO/DTO/BLA… se justifica.
E caso vc for usar, p/ copiar os valores das propriedades entre eles, vc pode usar o bom e velho BeanUtils.copyProperties(beanDestino, beanOrigem);
[quote=jgbt][quote=edpipole]
hum… legal… mais ai caso tenha um cliente remoto, tenho que seguir o conselho do pcalcado e minhas interfaces irão receber objetos simples serializados? mesmo porque não vou poder passar esse POJO uma vez que ele tem a regra de negocio junto certo?
[/quote]
Bom, nessa situação, como ja foi dito antes, o uso de VO/TO/DTO/BLA… se justifica.
E caso vc for usar, p/ copiar os valores das propriedades entre eles, vc pode usar o bom e velho BeanUtils.copyProperties(beanDestino, beanOrigem);
[]´s
[/quote]
tudo bem, então agora eu entendo quando falam VO/TO/DTO/XPTO não e uma boa ideia…
para sistemas não distribuidos podemos sem problemas usar POJO’s.
BeanUtils.copyProperties(beanDestino, beanOrigem);
contanto que os nomes dos atributos sejam os mesmos… isso vale…
para sistemas distribuidos também podemos usar POJO’s contanto que tenhamos o cuidado de manter a estrutura dos atribudos dos POJO’s em relação aos TO’s/VO’s/DTO’s/XPTO’s ai podemos usar o BeanUtils por exemplo… caso contrario teremos que estar dispostos a saber que o Desenvolvedor que criou a variavel nomeUsuario do DTO pensa diferente do desenvolvedor que criou o atributo usuario no POJO .
ai setamos de um para o outro na mão…