O que usar no lugar de VOs?

Pessoal, seria mto idiota criar um BO e dentro dele (somente dentro dele) um objeto DAO?
Assim o objeto de negocios poderia conter os atributos de estado, os metodos de negocio e a camada de persistencia encapsulada num objeto DAO mas q seria acessivel somente internamente ao BO…
Assim o BO seria sempre responsavel por armazenar o estado das variaveis… as regras de negocio e ainda a camada de persistencia… besteira oq eu falei? :oops:

Eu acho que muitas das coisas que estamos discutindo aqui já foram debatidas aqui:

http://www.guj.com.br/posts/list/60916.java

e aqui:

Muita coisa ficou clara pra mim após ler atentamente. Vale a pena dar uma olhada, principalmente no post do Kung.

Qual?

Isso é forçar a barra. Se você usar um cast para burlar as leis de static tyying o que te impede de acessar métodos privados diretamente?

[quote=victorwss]
A alternativa 1 é boa e funciona. O DAO cria o memento e o manipula como quiser. Daí ele salva o memento no objeto de negócio ou então o joga fora. Quase perfeito, o porém é que esse objeto memento não seria um TO disfarçado? Apesar de que mesmo que seja, o modelo já não é mais o anêmico, pois ao invés de todos usarem o TO, todos usam o objeto de negócio e o memento (TO disfarçado) só serviria para a comunicação com o DAO.[/quote]

Não é um DTO, é um memento. Aho que você etá assumindo que qualquer objeto que não é um objeto de negócios é (1)burro e (2)DTO, o que não é verdade.

Acho que você está fazendo uma confusão entre o que é um BO de um modelo anêmico e um Service (ou Façade). Um BO executa regras de negócio de forma prcedural, um Service apenas os objetos (Não-BOs) que executam as regras de negócio.

:idea: Talvez vocês se entendam mais se começarem a discutir em cima de exemplos (pode ser pequenos trechos de códigos).

Estava pensando naqueles problemas do EJB 2 e em outros problemas que a herança costuma trazer. Mas, após pensar um pouco sobre os problemas reais que isso pode trazer, confesso que não consegui pensar em nenhum problema real. Mas de qualquer forma prefiro evitar de ter que usar herança nesse caso, porque herança é algo que você usa só se você tiver certeza que é para usar (e eu não tenho certeza).

Sim, é forçar a barra. Mas isso é fácil de resolver com algum refatoramento.
Acho que uma factory no mesmo pacote que o objeto de negócio pode usar setters com visibilidade de pacote no objeto de negócio. Quanto aos getters não vejo problema, mas se houver também dá para resolver.

Quanto a acessar os campos diretamente via reflection, o System.getSecurityManager().checkAccess(blabla) cuida disso.

Vejamos. Eu sei que você já sabe muito bem o que é um (V|[D]T)O e está cansado de saber, mas vamos analisá-lo:

Um DTO é um objeto que contém:

  1. Um construtor sem parâmetros e quase sempre vazio.
  2. Um monte de atributos privados.
  3. Getters burros (que apenas retornam o valor do atributo) para cada atributo.
  4. Setters burros (que apenas fazem uma simples atribuição no valor do atributo) para cada atributo.

Alternativamente (e pior ainda) poderia conter apenas um construtor vazio e um monte de atributos públicos.

Um DTO pode também em alguns casos implementar Cloneable e/ou Serializable. Pode herdar de outro DTO (embora na minha opinião isso é horrível). E pode também sobrescrever métodos (tais como clone(), toString(), equals(Object) e hashCode()). E pode também usar annotations a vontade.

Mas enfim, a maior e pior característica do DTO é que ele não ter lógica de negócio alguma, e por causa disso os getters e setters são sempre burros, que é quase o mesmo que fazer os atributos serem públicos.

Agora eu pergunto sobre o memento: A estrutura dele não seria a mesma que um DTO? Um construtor sem parâmetros, um monte de atributos e um monte de getters e setters burros.

Apesar de que volto a frisar. A alternativa 3 já resolveu o problema do modelo anêmico, de separar dados de regras de negócio. Ela só não eliminou a necessidade de ter um objeto burro trafegando dados entre o negócio e o DAO (no caso o memento).

Porque pensar que algum objeto de dominio precisa ser criado por um caminhao de parametros?

Objetos de dominio são compostos por outros objetos de dominio e um dos principios da OO é a atribuicao de responsabilidades de maneira que nao haja objetos sobrecarregado de responsabilidades.

Se eu tenho um metodo/construtor com muitos parametros é um sinal que preciso criar um outro objeto capaz de agregar esse ‘caminhao’ de parametros em algum conceito que faca sentido no meu dominio.

editado: O que vcs acham?

editado: editado: O que vcs acham?

O que vc descreveu é um POJO ( Plain Old Java Object) , um objeto java normal, que não implementa interfaces especiais.
Detalhes um DTO sempre tem que implementar Serializable e mais do que isso deve implementa os metodos privados de read e write. Todo o objetivo do DTO é maximizar a eficiencia da transferencia entre nodos. A qual acontece via mecanismos de serialziação.

Mas os POJO tm costumam ser serializable quando estamos em ambientes JEE. A única coisa que os destingue dos DTO é a sua inificiencia no transporte já que eles não sobreescrevem o algoritmo de serialização.

O DTO é realmente burro. Sempre foi, sempre será. Essa é a sua função.
Existe um padrão chamado HashDTO que é um DTO baseado na interface get/put semelhante a um mapa.

A estrutura de um memento seria exactamente a de DTO ( ou um HashDTO que ainda é mais facil graças a reflection) o ponto é que o objeto de negocio não é um memento

class Pessoa  {

       Date nascimento;
       String nome;
 ... 

  public int idade (){}

  .. get/set
}


class MementoAdapter {

     public static Memento getMemento(Object obj){
           // usa reflection e faz :
        // ara cada campo de obj  seta o memento com memento.put(nomecampo, valorcampo)
     }

     public static void setMemento(Memento  m , Object obj){
           // usa reflection e faz :
        // para cada campo de obj  lê o memento com memento.get(nomecampo)
     }
}

class Memento  extends HashMap{}


// uso 

Pessoa p = new Pessoa();
p.setNome("Sergio");

Memento m = MementoAdapter.getMemento(p);

// Agora vc pode enviar o memento para o DAO outro nodo etc.. 
// A class de negocio não é persistivel, apenas o memento é.

O ponto é : porque criar um mento se eu posso colocar a logica do MementoAdapter dentro do DomainStore/DAO
e usar o pojo directamente como o seu proprio memento ? Basta que o pojo seja serializable ( para navegar entre nodos) , mas nem isso é necessário se a aplicação é apenas local.

Pojos como Pessoa, Cliente, etc… nunca serão DTO. Exemplo de DTO é uma implementação de List que use um algoritmo de compressão quando é serializado , ou uma List que saiba a estrutrua dos objetos dentro dela e otimize a serialização ( por exemplo, uma Lista de N objetos iguais não precisa serilizar N objetos, apenas 1).

Não ha nada a ser usado no lugar de Pojo para os objetos de entidade. Recentemente com annotations os Pojo ficaram mais poderosos ( embora façam import de annotações é aceite que eles ainda são independentes de interfaces especiais)

Objetos inteligentes ( frameworks) usam as definições dos pojos ricos (ricos porque contêm meta informação)
para os gerenciar e dicidir o que fazer. internamente esses frameworks podem até usar mementos, mas isso é uma escolha interna. (por exemplo se pessoa não é serializvel, mesmo assim posso ereplicar o seu estado usando mementos e tornar um objeto pessoa remoto com o mesmo estado que este)

As regras de negocio, consistencia etc, ficam nos objetos de serviço.
A prova de que é aceitável usar Pojo / DTO são os Webservices e todos os mecanismo relacionados e a entreprise bus. E é assim que as empresas reais funcionam. Dados são apenas isso, informação. O que fazer com ela é a alma do negocio e depende de cada um; de cada sistema

Essa é A única caracteristica que define um DTO como tal.

[quote=victorwss]Agora eu pergunto sobre o memento: A estrutura dele não seria a mesma que um DTO? Um construtor sem parâmetros, um monte de atributos e um monte de getters e setters burros.

Apesar de que volto a frisar. A alternativa 3 já resolveu o problema do modelo anêmico, de separar dados de regras de negócio. Ela só não eliminou a necessidade de ter um objeto burro trafegando dados entre o negócio e o DAO (no caso o memento).
[/quote]

Memento não é DTO, pelo contrário, se fosse usa-lo neste caso eu o implementaria como parte do domino. Repito, não são os parâmetros do construtor, atributos ou getters/setters ‘burros’ que definem o DTO, mas a ausencia de logica de negocios, e não há nenhuma obrigacao nesse sentido para objetos memento.

Particulamente não vejo problemas em usar reflection nesses casos, ou entao metodos setters. Neste ultimo faco o possivel para nao ter "setters inteligentes" nos meus objetos de dominio assim consigo defini r um padrao onde todos os setters existem apenas por uma questao de infraestrutura (negocio <-> DAO).

Espero ter sido claro.

Depende do dominio que vc esta lidando ne? Eu posso resolver um problema do meu negocio usando memento, qual o problema nisso?

Pois é, achei esse exemplo de memento overkill neste caso.

Sim, cuida disso e você não consgue usar JPA, Hibernate e praticamente qualquer outro framework ou biblioteca modernos que dependem disso propriamente.

Isso não é a decrição de um DTO. Um DTO é algo que transfere dados, não existe nnhuma especificação sobre ter construtor vazio ou o que quer que seja.

Novamente: DTO não implica em ter get/set burro, DTO é uma coia, objeto burro é outra. Você pdoe implementar o DTO come struturas de dados (i.e. objetos burros) ou não.

Da mesma forma você pode implementar um memento usando estruturas ou não.

[quote=victorwss]
Apesar de que volto a frisar. A alternativa 3 já resolveu o problema do modelo anêmico, de separar dados de regras de negócio. Ela só não eliminou a necessidade de ter um objeto burro trafegando dados entre o negócio e o DAO (no caso o memento).[/quote]

Não vejo este problema. Se você realmente quer usar um memento para isso (que eu citei como uma alternativa mas só é útil em casos extremos, creio) você pdoe mantêr toda esta lógica na Camada de Persistência. Ainda que não mantivesse, como ja disse antes domínio anêmico não é ter estrutura de dados, e utilizar estruturas de dados para regras de negócio. Popular um objeto não é regra de negócio.

É, esse tópico está ficando grande :smiley:

Pois bem, na página anterior onde eu disse:

Leia-se:

Pronto, agora a descrição está melhor. :stuck_out_tongue:

Sim, o caminhão de parâmetros é uma coisa ruim, mas ele seria necessário para fazer o objeto nascer consistente. Criar um outro objeto para isso é mais ou menos o mesmo que criar o memento, e resolve esse problema.

:shock: Eu pensava que o (V|[D]T)O não tinha nenhuma função real, era simplesmente uma aberração arquitetural do modelo anêmico desnecessária e que devia ser eliminada. Tanto que o título deste tópico é “O que usar no lugar de VOs?”. Já vi artigos do Martin Fowler metendo o pau nisso, vários tópicos aqui no GUJ dizendo que isso não presta e o wiki do pcalcado também.

Tell me more, please.

Não entendi.

Eu acho que o que está havendo aqui é uma confusão de conceitos, pelo fato de que essas siglas se referem a mais de uma coisa e algumas dessas coisas não são muito bem definidas e podem ser interpretadas de distintas formas. O (V|[D]TO) ao qual me refiro é aquele bicho do modelo anêmico que contém um monte de atributos e um monte de getters e setters burros e mais nada ou quase nada além disso.

Concordo plenamente.

Certo, acho que você tem razão. Se você precisar do JPA e não puder ter permissão de reflection, você se fode e a única coisa que dá para fazer é chorar. Esse é o grande problema de ferramentas que abusam de reflection. Ofuscadores de código também são outra coisa que fodem total com o reflection.
Apesar que tem aquela classe PrivilegedAction lá que acho que pode resolver esse problema, só que eu não faço idéia de como funciona e eu nunca usei.

Eu não disse que havia problema, só disse que ele não eliminou a necessidade do objeto burro.
Mas, eu não entendi o porque de “casos extremos”, pensei que fosse uma alternativa comum e não apenas para casos extremos.

Quanto a parte do “Ainda que não mantivesse, como ja disse antes domínio anêmico não é ter estrutura de dados, e utilizar estruturas de dados para regras de negócio. Popular um objeto não é regra de negócio.”, eu concordo plenamente.

[quote=cmoscoso][quote=sergiotaborda]
…o ponto é que o objeto de negocio não é um memento
[/quote]

Depende do dominio que vc esta lidando ne? Eu posso resolver um problema do meu negocio usando memento, qual o problema nisso?
[/quote]

Não depende do dominio. Depende do mecanismo de persistencia que vc usa. O padrão Memento original é um padrão para resolver a persistencia do objeto. Isso é feito criando um segundo objeto e copiando o estado do primeiro. Este segundo objeto é chamado ele proprio de memento. O ponto é que o objeto de dominio não é serializável e contém metodos de dominio. O memento não contém absolutamente métodos nenhuns. Ele é apenas um conjunto de atributos cujos valores são copiados dos atributos do objeto principal. Esse objeto memento pode ser serializável, persistivel etc. O ponto é que o objeto de dominio tem o seu estado preservado fora dele mesmo. Isso é o conceito de persistencia.

Vc não desenvolveria negocios com memento. Vc desenvolveria mecanismos de persistencia que fazem uso do padrão memento. Os seus objetos de negocio poderia ser mais ou menos dependentes do padrão conforme a sua implementação. Se usar reflection qq pojo serve. Se usar alguma interface especial os seus objetos de dominio vão depender de um framework, o que, em tese, é ruim. Enfim, o ponto é que Memento tem a ver com mecanismo de persistencia e não com negocios ou dominios.

[quote]
Pois é, achei esse exemplo de memento overkill neste caso.[/quote]

O ponto é separado em duas partas: 1) demonstrar que o padrão memento é utilizado sim, mas não como o GOF definiu. O estado do objeto é copiado para um outro objeto e esse objeto é que é persistido. Na recuperação é ao contrário. O detalhe é que os frameworks de persistencia abdicam do objeto intermediário e passam diractamente para a tecnologia de persistencia ( normalmente SQL).
2) Vc pode criar um mecanismo de persistencia que use o padrão memento com reflection. Assim seus objetos de dominio não dependerão do mecanismo e nem têm que ser serializáveis ou qq coisa assim. Depois vc cria uma interface padrão para persistir esses mementos usando o padrão Strategy. Ou seja, cria várias estratégias de persistencia. Uma delas será persistencia em banco de dados. Outra pode ser usando JCache ou JGroups para ter um estado compatilhado e distribuido ( uma especie de cloud). Outra pode usar um mecanismo de prevalencia. etc… Como esses mecanismo apenas irão depender do objeto memento )que pode ser algo muito simples como um HashMap , por exemplo) vc pode reaproveitar esse mecanismo de persistencia ad infinitum.
Junto com outros padrões como QueryObjet e Interpreter vc pode criar um DomainStore independe do dominio à semelhança do que é feito em JPA/Hibernate mas que funciona não apenas para bancos de dados.

Em 3 palavras: Dao is Dead.
É tempo de pensar mais além.

Concordo com voce, nao é um padrão de domain model mesmo!

Mas não restrinja memento a persistencia apenas, o padrao diz mais respeito a externalizar o estado do objeto do que preservar o estado fora do mesmo.

[quote=sergiotaborda]
2) Vc pode criar um mecanismo de persistencia que use o padrão memento com reflection. Assim seus objetos de dominio não dependerão do mecanismo e nem têm que ser serializáveis ou qq coisa assim. Depois vc cria uma interface padrão para persistir esses mementos usando o padrão Strategy. Ou seja, cria várias estratégias de persistencia. Uma delas será persistencia em banco de dados. Outra pode ser usando JCache ou JGroups para ter um estado compatilhado e distribuido ( uma especie de cloud). Outra pode usar um mecanismo de prevalencia. etc… Como esses mecanismo apenas irão depender do objeto memento )que pode ser algo muito simples como um HashMap , por exemplo) vc pode reaproveitar esse mecanismo de persistencia ad infinitum.
Junto com outros padrões como QueryObjet e Interpreter vc pode criar um DomainStore independe do dominio à semelhança do que é feito em JPA/Hibernate mas que funciona não apenas para bancos de dados.

Em 3 palavras: Dao is Dead.
É tempo de pensar mais além.[/quote]

Perfeito! Merece ir pro meu favoritos :slight_smile:

Como em tudo na vida, e informática não diferente, é preciso conhecer a Historia (com H) para entender os contextos das conversas. Eu tento usar os conceitos padrão tanto quanto possivel.
O DTO é realmente um padrão e é realmente util quando bem utilizado. A questão é que a os J2EE Core Patterns no tempo do EJB 1 e 2 disseram assim “cara, ejb entity é muito bom, mas tem o problema quando se usa de outra máquina. Existe muito overhead de manter o gerenciamento à distancia” e ai eles pensaram
"recomendamos que se usem objetos para o transporte da informação em vez de invocar os set/get remotamente para diminuir o overhead" Os objetos de transporte eram os DTO, mas com uma estrutura tão simples que nã otinha como otimizar o algoritmo de serialização ( o algoritmo padrão já é muito bom)
Então os DTO entram em cena. Como eles não eram realmente especializações de serialização a sun começou a chamade de VO (Value Object) porque era como se o valor ( o estado) do entity fosse transferido mas não o proprio entity em si, que apenas existiria no servidor ( isto é o padrão memento em ação)
O Martin Fowler inventou um outro padrão que não tem nada a ver com isto e que tb se chama VO.
Para diferenciar o VO do Fowler do VO da sun , o segundo começou a se chamar só TO ou DTO como antigamente (embora ele não seja um DTO verdadeiro).

O modelo anêmico nasceu do EJB ser uma salada que separa dados (entidade) se acções ( servico).
Note que a dualidae Entidade-Serviço está presente tanto em EJB quanto em DDD. O que muda são as implementações e responsabilidade. Mas no EJB existia esse TO voando entre as máquinas, que no DDD nem faz sentido ( porque o dominio não coisa de problemas de infraestrutura)

Mas o modelo anemico tem o seu proposito. Todas as tecnologias B2B funcionam dessa forma.
Vc precisa saber qual é a filosfia do seu desenvolvimento e as tencologias que vai usar antes de decidir que usar DTO é ruim.

Não ha muito a dizer. Em vez de vc criar uma classe por cada coisa que quer transferir , Cliente, produto etc…
Vc tem apenas uma classe, um HashMap que vc seta pares nome:valor e pronto. É mais simples de usar por frameworks mas mais dificil por pessoas.

O pojo é objeto que transita nas tencologias de hoje. Não se eliminou o DTO, elinou-se o EntityBean como uma coisa à parte. No EJB 3 os pojos são as entidades. A entidade é “abstracta” no sentido que ela é definita por anotações e não mais uma interface especial. Os pojos ebj3 são ao mesmo tempo TO e Entidades. O Hibernate usa esta ideia e como se sabe o JPA tem a mesma ideia do Hibernate.
O memento que viajava pela rede não foi eliminado. Foi aceite. E a tencologia mudou para dar cobertura a esse paradigma.

Em EJB o dominio é “anemico” por default e não tem outoro jeito. Por isso que coisas como Spring e DDD apareceram. Porque o EJB desafia o conceito de que as logicas devem estar atreladas ao objeto. EJB é uma solução tecnica para um dominio em ambiente distribuido.
O DDD é uma ideia boa ,mas apenas para modelagem do dominio. Quando chega na parte de implementar isso na prática com tecnologias reais e requistos não funcionais poderosos como distribuição o DDD começa a ser um problema como podemos ver pela quantidade de post sobre como implementar Repository ou como gravar um Entity no banco. São duas esferas diferentes.

Não, isso Não é um DTO típico. Um DTO típico é um objeto otimizado apra trafegar em reder e outras mídias de baixa performance.

O que ele disse, com muita razão, é que um objeto é composto d eoutros então Não faz sentido você recbeer muitos parâmetros pequenos e sim alguns poucos objetos que encapsulam estes parâmetros.

Você provavelmente pulou algun pontos importantes do texto.

http://fragmental.com.br/wiki/index.php/Evitando_VOs_e_BOs#Transfer_Objects.2FValue_Objects

Um DTO não é necesariamente um objeto burro, ele é um objetoe specializado.

Recomendo que antes de prosseguir ensta discussão você leia sobre os apdrões ciados aqui.

Como disse isso Não é um DTO, é uma estrutura de dados (i.e. struct) que não deveria er comum num programa OO.

O fatod e que Não teria eliminado a necessidade do objeto burro seria o problema, que eu não concordo.

Não, não é comum. Na maioria dos casos gets e sets são suficientes e esse carnaval de patterns e herança só é preciso se você possui um caso muito estranho ou está sendo muito preciosista.

Ótima observação! Pelo menos me serve de consolo… risos.
Quando surge uma nova idéia de Pet Project sinto-me obrigado a aplicar repositories. Aí, só o tempo que perco pensando em como aplicá-lo é suficiente para dar o tempo natural de desgaste da empolgação pelo Pet Project.

Não concordo totalmente com isso, justamente pq domínio e infraestrutura são esferas diferentes.
Quer distribuir objetos, ótimo, utilize Session Façades e preserve seu domínio. A(s) entidade(s) rica(s) podem inclusive pertencer como atributos destes beans em um modelo Stateful e terem seus estados mantidos e distribuidos em várias requisições.

Não vejo onde Domain-Driven influencia na distribuição de um sistema.

[quote=Thiago Senna]Ótima observação! Pelo menos me serve de consolo… risos.
Quando surge uma nova idéia de Pet Project sinto-me obrigado a aplicar repositories. Aí, só o tempo que perco pensando em como aplicá-lo é suficiente para dar o tempo natural de desgaste da empolgação pelo Pet Project. [/quote]

Talvez o problema seja exatamente que você perde muito tempo pensando em como aplicá-los. Para isso serve refatoração. Como o Alessandro falou abaixo são coisas dierentes, você não deveria mudar o domínio em unção da infra, pelo menos não com frequência.

Tudo bem. Mas quantos sistemas distribuidos vc fez sem usar EJB ?