O que usar no lugar de VOs?

[quote=sergiotaborda]
Tudo bem. Mas quantos sistemas distribuidos vc fez sem usar EJB ?[/quote]

Não entendi. O que tem a ver EJB com DDD?

[quote=pcalcado][quote=victorwss]
Leia-se:

[/quote]

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.
[/quote]

Ok, não importa o nome. O que eu me refiro é àquela coisa do modelo anêmico equivalente a um struct, e sempre que falo em VO, TO, ou DTO eu estou me referindo simplesmente aquilo e nada mais além do que aquilo, o nome não importa. Se ele é otimizado para trafegar em rede, se é usado para EJB ou se é usado no framework X ou no framework Y também não me importa. Eu abri esse tópico para entender como eliminá-lo, e não como usá-lo ou como nomeá-lo! O meu objetivo ao abrir este tópico é simplesmente dizer adeus a ele e nunca mais voltar a vê-lo.

Volto a dizer: O que eu me refiro é ao struct do modelo anêmico. O nome não importa. Se vai trafegar em rede ou em EJB também estou me lixando pra isso.

Ok, evita-se o uso do memento e o reserva para casos onde você você necessita de mudanças de estado mais complexas e atômicas (ex: Cidade e UF, ou os dois, ou nenhum).

Me cite um caso que utilizar o modelo anêmico seja a melhor solução. (Modelo anêmico = usar structs burros em todas as camadas).

Talvez para alguns frameworks seja bom, mas acho que para uso geral, isso é muito pior que o modelo anêmico, pois a capacidade do compilador verificar seu código é menor.

[quote=victorwss]
Ok, não importa o nome. [/quote]

Victor, só uma dica: eu diria que 50% da importância de padrões, de projeto, arquiteturais ou o que for, é com relação a criarmos uma nomenclatura comum para nos referirmos às soluções. O nome que usamos ao nos referirmos a um padrao é muito importante, bastou você dizer que está falando de struct e não de TO/DTO que a coisa mudou completamente.

[quote=pcalcado][quote=victorwss]
Ok, não importa o nome. [/quote]

Victor, só uma dica: eu diria que 50% da importância de padrões, de projeto, arquiteturais ou o que for, é com relação a criarmos uma nomenclatura comum para nos referirmos às soluções. O nome que usamos ao nos referirmos a um padrao é muito importante, bastou você dizer que está falando de struct e não de TO/DTO que a coisa mudou completamente.[/quote]

O problema desses structs é que eles não tem um nome apropriado. Eles são chamados ora de VOs, ora de TOs e ora de DTOs. E cada uma dessas siglas corresponde a uma outra coisa diferente, o que gera muita confusão.

Pois bem, então de agora em diante o chamemos de “struct anêmico”, ok?

[quote=victorwss] Eu abri esse tópico para entender como eliminá-lo, e não como usá-lo ou como nomeá-lo! O meu objetivo ao abrir este tópico é simplesmente dizer adeus a ele e nunca mais voltar a vê-lo.
[/quote]

A moral da historia é: vc não consegue eliminá-lo.
Vc consegue dar-lhe mais capacidades. Criar métodos de dominio e/ou negocio. Mas vc não consegue viver sem ele.

Procure por Enterprise Service Bus.
Nessa arquitetura os dados são desprovidos de metodos e transferidos com base em xml.
Eventos de processamento (um especia de trigger) são setados para os dados serem processados por serviços.
Os serviços podem ser constuidos por vc ou por terceiros. Os dados idem. Não ha uma correlação entre ambos.
Existem mecanismos de tranformação que adquam os dados os serviços. Nesta arquitetura em que fatores como volume e distribuição são importantes o modelo é completamente anêmico no sentido que os dados não sabem de logicas.
Esta arquitetura tem relação com os webservices e em geral com SOA (Service Oriented Arquitecture) - onde os serviços são mais relevantes que os dados. Por oposição a sistema de bancos de dados onde o foco são nos dados.

Vc pode melhorar o padrão com uso de Generics para aumentar o strong typing, mas sim, é um padrão virado para ferramentas.

[quote=sergiotaborda][quote=Lezinho]
Não vejo onde Domain-Driven influencia na distribuição de um sistema.
[/quote]

Tudo bem. Mas quantos sistemas distribuidos vc fez sem usar EJB ?[/quote]

Só uso EJB quando faz parte de requisitos, realmente não é o modelo que mais me agrada (tão quanto um modelo de distribuição que o faça necessário).
Mas também não sei onde DDD tem haver com isso …

[quote=Lezinho][quote=sergiotaborda][quote=Lezinho]
Não vejo onde Domain-Driven influencia na distribuição de um sistema.
[/quote]

Tudo bem. Mas quantos sistemas distribuidos vc fez sem usar EJB ?[/quote]

Só uso EJB quando faz parte de requisitos, realmente não é o modelo que mais me agrada (tão quanto um modelo de distribuição que o faça necessário).
Mas também não sei onde DDD tem haver com isso … [/quote]

Eu já tinha respondido a isto mas parece que não ficou…

O que queria perguntar era: Quantos sistemas como EJB e DDD já fez ?

Quando vc faz um modelo distribuido em que o cliente é minimamente inteligente vc precisa do modelo de dominio no cliente tb.
Se vc usar um repositorio no cliente o repositorio tem que se reportar ao repositorio central no servidor. As entidades que vc controla precisam de mais mecanismos como controlo de concurrencia via um campo version. E ai , ou o seu modelo deixa de ser puramente DDD e contém coisas como getVersion() ou vc força o modelo DDD e tem que se haver com esses detalhes tecnicos.Vc não pode delegar todos os serviços ao servidor pq isso tem baixa performance, logo pelo menos alguns têm que ter inteligencias locais.
Sim, pode usar um Façade mas ele tem que ser esperto para distinguir se está sendo chamado no cliente ou no servidor. Este problema não se poe se aplicação é web ou só desktop, mas quanto é distribuida em muitos desktop a coisa complica.
Pelas documentações do DDD e pelas conversas no foruns parece que DDD foi inventado enquanto se faziam programas fechados ( ou seja, em que ha criação do codigo end-to-end) e não parece que haja um resposta para usar DDD em sistemas em que ha intervenção de tecnologias conhecidas. Para começar a implementação de repository já causa dor de cabeça em sistemas não distribuidos.

Enfim, se o sistema é distribuido ( digamos que com EJB) usar DDD vira um anti-pattern porque o seu conceito de nucleo de dominio independente do resto, não funciona. Bom, pelo menos não vi funcionar. Por isso perguntei quantos sistemas assim vc fez já que defendeu que não ha problema em usar DDD em ambiente distribuido.

E não vale dizer que usa apenas os conceitos de Serviço, Entidade, VO , Repositorio porque isso já existe no EJB.
Para ser DDD tem que ter o conceito de nucleo independente de infra (pelo menos parecendo independente).

[quote=sergiotaborda]Enfim, se o sistema é distribuido ( digamos que com EJB) usar DDD vira um anti-pattern porque o seu conceito de nucleo de dominio independente do resto, não funciona. Bom, pelo menos não vi funcionar. Por isso perguntei quantos sistemas assim vc fez já que defendeu que não ha problema em usar DDD em ambiente distribuido.

E não vale dizer que usa apenas os conceitos de Serviço, Entidade, VO , Repositorio porque isso já existe no EJB.
Para ser DDD tem que ter o conceito de nucleo independente de infra (pelo menos parecendo independente).[/quote]
Você pode explicar melhor o que você quiz dizer nesse finalzinho? Acho que a grande maioria das pessoas neste forum não conseguiu entender o seu ponto de vista ou todos nós estamos viajando muito na maionese …

[quote=emerleite]

[quote=sergiotaborda]
E não vale dizer que usa apenas os conceitos de Serviço, Entidade, VO , Repositorio porque isso já existe no EJB.
Para ser DDD tem que ter o conceito de nucleo independente de infra (pelo menos parecendo independente).[/quote]

Você pode explicar melhor o que você quiz dizer nesse finalzinho? Acho que a grande maioria das pessoas neste forum não conseguiu entender o seu ponto de vista ou todos nós estamos viajando muito na maionese …[/quote]

não sei se entendi sua duvida… acho que se refere aos conceitos não formarem o DDD e sim a ideia de nucleo independente.

Bom, não sei como dizer melhor. Em EJB vc tem Serviços (stateless, statefull e message beans) , vc tem entidades
Entity Bean , voce pode ter VO (Integer , Date, são VO logo é dificil não os ter)
Repositorio também já que ha recomendações de usar o padrão DAO com EJB onde as Entidades são realmente guardadas. A diferença é que o DDD se posiciona para resolver o problema de modelagem do dominio. Apenas e só de dominio. Nada mais. não, obviamente, o repositorio do DDD não pode ser entendido como um tradutor/mapeador de tecnologias como o DAO, embora (acho que seja tb obvio) a escolha é no final de quem implementar o repositorio. É apenas o conceito que importam em DDD. O conceito de um objeto que representa a coleção de entidades como se fosse uma lista. A chave é “como se fosse”. Já dá a entender que sabemos que não é.

Portanto, apenas identificar os conceitos e usar os conceitos que o DDD usa, não é realmente estar usando DDD, é ser influenciado pela nomenclatura/ idiologia. O EJB usa uma nomenclatura semelhante e os conceitos são semelhantes. Se vcs perderem um pouco de tempo pensando como modelar um dominio, vc vão chegar no conceito do DDD. Se pensarem em como o implementar de forma distribuida vão chegar no EJB, mas os conceitos são os mesmos nos dois.

Então o que faz o DDD diferente ? Apenas a modelagem do dominio. Como o DDD apenas modela o dominio ele abstrai tudo o que não for de dominio. toda a infra é abstraida. Isso é feito com dois mecanismos : o Repositorio que abstrai o modelo da camada “abaixo” e os serviços que o isolam da camada “acima”. No centro estão as entidades que não tem nenhuma relação com infra nenhuma. Nem uma anotation sequer. Essa pureza do DDD é viável em sistemas completamente escritos do zero como poderia ser uma aplicação swing de criação de circuidos integrados , mas é complexa de implementar num ambiente distribuido.
Em ambiente distribuido existem muitos controles necessários ao estado das entidades ( aliás é por isso que o hiberante não é transparente em ambiente distribuido porque a sessão não é distribuida) como o DDD não enxerga isso, integrar as duas coisas é complexo.

Portanto, se vc tem uma entidade com alguma ponta de infra: vc não está usando DDD , vc está apenas sendo influenciado por ele.

Você não explicou a frase que diz que quando um sistema é distribuido usar DDD é um anti-pattern.

E mais, você pode modelar seu domínio e utilizar os Metadados das annotations para tirar o rastro, mas sinceramente nunca farei isso só pra dizer que meu Domínio é DDD compliance (Sé é que posso dizer isso). Deixo esse purismo de lado que nesse caso não serve pra nada. Prefiro ser mais prático, afinal, nesse caso não existe um jeito muito decente de integrar o domínio a infra sem essas anotações ou XMLs do inferno.

[editado]
E outra coisa, o fundamental do DDD nada tem a ver com isso que você está falando. Usar meta-dados ou não é uma questão que fica fora do Design do Domain Model. Esse “mau necessário” não invalida todo o resto dos conceitos.
[/editado]

[quote=sergiotaborda]
(…). As entidades que vc controla precisam de mais mecanismos como controlo de concurrencia via um campo version. E ai , ou o seu modelo deixa de ser puramente DDD e contém coisas como getVersion() ou vc força o modelo DDD e tem que se haver com esses detalhes tecnicos.(…)

Enfim, se o sistema é distribuido ( digamos que com EJB) usar DDD vira um anti-pattern porque o seu conceito de nucleo de dominio independente do resto, não funciona. Bom, pelo menos não vi funcionar. Por isso perguntei quantos sistemas assim vc fez já que defendeu que não ha problema em usar DDD em ambiente distribuido.

E não vale dizer que usa apenas os conceitos de Serviço, Entidade, VO , Repositorio porque isso já existe no EJB.
Para ser DDD tem que ter o conceito de nucleo independente de infra (pelo menos parecendo independente).[/quote]

Sinceramente, acho questão de bom senso. Não acredito e acho purismo sem ganho efetivo, defender que um version estragaria toda sua modelagem orientada ao negócio. Como você mesmo menciona, nem todos os serviços são remotos (ou pelo menos não deveriam), o overhead da rede seria latente e isso já reduz sua gama de esforço para satisfazer a infra.

Eu utilizo Seam, pra mim EJB é amigo e não inimigo. Não utilizo distribuição para tudo, pq a distribuição é apenas mais uma feature do EJB e não toda sua motivação, por tanto para a maioria dos casos utilizo interfaces locais. A gerência transacional e de estados de beans pelo conteiner já é algo excelente a considerar para sua utilização. No caso de distribuição de objetos eleitos “remotos”, apenas adiciona uma fachada se acaso sua operação for direta em entidades, ou altero seu metadado para remoto no caso de interfaces de repositórios e services.

Fora os cases atuais em EJB3 e frameworks como o SEAM, tenho modelo rodando na Argentina de sistema de integração com EJB2.1, onde o domínio é isolado por façades e o negócio é fluente. Obviamente a distribuição é limitada pq é um sistema de integração, portanto os métodos remotos são específicos e repassam para o Domain o necessário de informação, nada mais. Nunca tive problemas …

Um modelo “lá e cá” distribuído por EJB, com grande massa de Domínio entre clients e servers na maioria dos casos, é um overkill tremendo que quase sempre pode ser evitado por outras opções de arquitetura. Em muitos casos, um simples modelo REST resolve (mas isso não muda a questão da distribuição dos domínios, o que é mais estratégico do que técnico).

Sergio, não daria para fazer algo assim:

Pacote 1 (ou projeto 1) contém toda a sua lógica DDD, sem annotations e sem EJB.

Pacote 2 (ou projeto 2) adapta DDD ao EJB. Contém um monte de Façades para os objetos DDD com todas as annotations necessárias.

E aí, o que acha?

Se vc tiver uma aplicação swing que se comunica com o servidor vc pode usar SEAM ?
Se vc usa interfaces locais seu sistema é distribuido ?

Quando digo distribuido digo :“roda em nodos diferentes” e não "roda em camadas/containers diferentes"
Existe serialização envoldia e o mesmo dado logico está em diferentes lugares fisicos (jvm).

Não sou eu que acha que getVersion é violar o purismo do DDD. Isso é obvio. getVersion não é uma método de dominio nem de negocio, logo não pertence na entidade. Claro que ha formas de criar um getVersion sem conspurcar a class de dominio (Proxies que herdam a classe e implementam uma interface de controle) mas o ponto é que se eu declarar explicitamente estarei violando o DDD. A única forma de usar DDD em ambiente distribuido é injetar um monte de proxies que deixa o dominio livre de infra. Quem faz isso ?
Eu concordo que é purista: mas hei! conceitos são coisas puristas. Como disse, na prática vc não usa DDD porque é demasiado restritivo (é um anti-patern: um padrão que atrapalha). Vc usa uma modelagem de dominio, se inspira até nos conceitos , mas como já disse , esses conceitos não são propriedade do DDD.

Tb não digo que annotations, metadados em geral, sejam maus. Mas porque vc precisa de metadados ?
Para trabalhar com os dados de forma automática. Ora, em DDD , em tese, isso não é necessário porque o sistema é feito do principio pensandos nas entidades do sistema. Não é generico. não ha frameworks, não ha truques. Tudo é simples e de desenvolve em torno do dominio. Não visa ser um padrão tecnologico, apenas de modelagem. Eu nunca disse que era ruim usar metadados. O que eu disse é que colocar
imports no arquvio da entidade que sejam de infra é contra a ideologia DDD. Mas eu tb disse que essa ideologia pará no dominio. Então a construção da aplicação, da infra, é livre. Mas não me digam que é aceitável usar getVersion em DDD porque não é. Isso é resultado de trade-off ou de gambiarra, não da teoria que o DDD defende.

Em sistemas distribuidos onde as logicas têm que estar em mais do que um ponto do sistema, os nucleos de dominio têm que ser sincronos. Esse sincronismo é feito à custa de tencologia e truques de manipulação como proxies dinamicos. Então, porque me dar ao trabalho de criar um sistema purista se usar EJB (ou qq outra tecnologia distribuida) já resolve ? Não vou. Então porque me preocupar com os v[D{T}]O se eles são necessários a uma prática menos purista mas mais pragmática ?

O meu ponto era apenas:
1)Colocar logicas nos objetos de dados é uma ideia do DDD e de OO em geral. Essa ideia é boa em tese e executável em certo limite como o pessoa.getIdade () ou produtoItem.getCusto() em que ha uma redução a operar sobre os dados já contidos no objeto. Essas logicas nunca farão o sistema funcionar. O proprio DDD admite isso ao entender a necessidade dos Serviços.
2)Por outro lado usar V[D{T}]O é o que se faz em tenologias modernas como EJB 3 e em qualquer framework que se destine a ser generico. A persistencia não se importa com o comportamento, apenas com os dados e sempre, sempre, ela usará V[D{T}]O porque ela é “forçada” a seguir o padrão Memento.
3) Desafiar a separação entre V[D{T}]O e Serviços não faz sentido nem em DDD nem em nenhum modelo de dominio que se preze. Nem EJB faz isso. O modelo anémico é realmente o que é usado na prática e não ha como ser de outra forma quando queremos usar tencologias de mercado. Portanto não ha como se livrar do V[D{T}]O se queremos ser práticos e menos puristas.
3.1) se quiser ser purista pode, mas em sistemas limitados, não distribuidos. Em sistemas distribuidos a pureza é um empecilho e isso rápidamente significa que se não ha purismo, não ha porque eliminar os V[D{T}]O.

É boa ideia criar um getIdade e um getCusto, concerteza. Mas criar um conta.transfere(100, conta) é errado.
E parece ser ha uma defesa da segunda quando na realidade tudo o que se pede é a primeira.

Não ha necessidade de eliminar os V[D{T}]O o que ha necessidade de eliminar é codigo assim:


double preco = produto.getPreco();
double quantidade = produto.getQuantidade();

double custo = preco * quantidade;

if (custo > 200.00){
    desconto = 100.00;
} else {
    desconto =0;
}

// e

Date nascimento = pessoa.getDataNascimento();

Calendar nascimentoCalendar = Calendar.getInstance();
nascimentoCalendar .setTime(nascimento);
Calendar agoraCalendar= Calendar.getInstance();
agoraCalendar.setTime(new Date());

int idade =   agoraCalendar.get(Calendar.YEAR) - nascimentoCalendar .get(Calendar.YEAR);

if (agoraCalendar.get(Calendar.MONTH) < nascimentoCalendar.get(Calendar.MONTH) || (agoraCalendar.get(Calendar.MONTH) == nascimentoCalendar.get(Calendar.MONTH) && agoraCalendar.get(Calendar.DATE) < nascimentoCalendar.get(Calendar.DATE))){
   idade--;
} 

por

desconto = produto.getCusto()>200.00 ? 100.00 : 0.0;
idade = pessoa.getIdade();

As pessoas tendem a programa a mesma logica para o mesmo calculo cada vez que precisam dela. Isso que é errado. Isso que deveria ser eliminado e não os pobres dos V[D{T}]O

[quote=victorwss]Sergio, não daria para fazer algo assim:

Pacote 1 (ou projeto 1) contém toda a sua lógica DDD, sem annotations e sem EJB.

Pacote 2 (ou projeto 2) adapta DDD ao EJB. Contém um monte de Façades para os objetos DDD com todas as annotations necessárias.

E aí, o que acha?[/quote]

Daria. E em tese é assim de que deve ser.
O ponto é: vc consegue fazer ? Alguem consegue ? É mais facil ou dificil que usar EJB directamente ?
Meu cliente não quer EJB, dá para fazer como Hibernate e Spring ? Dá para fazer distribuido com Hibernate e Spring ? Não tem problemas de cache ou latencia ou carga ? …

Sim, e com várias opções (utilizando jbossmc, @Remote e scriptings, tunelamento http/webservice), etc. Nas próximas versões isso só esta melhorando …

Eu falei que só uso interface locais ou disse que a maioria das interfaces possuem apenas a necessidade de serem locais?

[quote=sergiotaborda] Quando digo distribuido digo :“roda em nodos diferentes” e não "roda em camadas/containers diferentes"
Existe serialização envoldia e o mesmo dado logico está em diferentes lugares fisicos (jvm). [/quote]

Eu disse o contrário?

… é, acho que o ponte de corte faltante então seja o não menos importante na arquitetura de um projeto, o chamado “bom senso”. getVersion não mata ninguém Sergio, tão pouco sua modelagem (assim como hashCode, toString e outros tbm não). :wink:

Eu estava só esclarecendo a minha posição.
E concordo que não mata ninguem. Eu já passei por essa escolha. No fim usei o getVersion, mas sempre fica a impressão que é gambiarra já que o correto é usar um proxy dinamico. ( Veja por outro lado: getVersion não pode ser usado para tomar decisões no dominio, mas o fato dele ser publico e disponivel a qq ambiente permite que o programador faça asneira. É um trade-off , mas não é tão simples quanto vc faz parecer)

Sérgio, dizer se getVersion descaracteriza DDD ta beirando o absurdo vai? Você está se prendendo ao pé da letra e não nos conceitos. Todo livro que eu leio eu tento pegar os conceitos e aplicar da “melhor maneira possível”. Repetindo: “melhor maneira possível”. Em Java, a “melhor maneira possível” de aplicar os conceitos, acredito ser a que estamos falando, com metadados das annotations, getVersion, etc.

Claro que uma aplicação sem Hibernate/JPA não vai ter getVersion, etc. Poderiamos fazer tudo com XML de mapeamento ou SQL dentro do DAO (ARGH), controlar o lock dos registros no braço, em fim, tudo como era antes. Também não acho o melhor dos mundos a forma como é feita hoje.

Agora te pergunto: tem alguma “melhor maneira possível” além dessa? Eu sinceramente não conheço. E outra: Essas coisas tornam DDD um anti-pattern quando usado com EJB como você falou?

Bom, o que vejo é que isso tudo acaba mesmo em questão de pontos de vista.

Na visão pragmática dos conceitos, realmente qualquer atributo diferente do model não se encaixa bem. Fora do conceitual e em termos de aplicabilidade, alguns acréscimos necessários, como dependencias de metadados em código ou métodos que satisfaçam a linguagem e não o negócio, acabam caindo em uso.

O que é certo ou errado, acho que não tem resposta. O sucesso de um design é medido no desempenho da equipe, na fluência do código e do resultado final junto com o cliente e sua resposta a mudanças. Se a variação do método for chamada de DDD, MyDDD, ou CustomDDD, acho isso o ponto de menor relevância.

[]'s

Bem política sua resposta, mas tudo bem :smiley: