Anemic Domain Model e sistemas sérios

Quando nos ensinam OO sempre nos dizem que os objetos devem traduzir a realidade. Se o sistema é bancáro deve existir Conta e Banco e assim vai. E a isso se chama domain model (modelo de dominio). Mas as tecnologias java , especialmente jee , mas não só não nos levam a criar esse tipo de objetos, mas sim objetos que representam registros (linhas no banco de dados) e objetos que representam operações sobre eles. Isso gera os famosos DO , TO , DTO … escolham … e os Façades/Statless bean etc… modelo que se chamou de Anemic Domain model , modelo de dominio anémico.

Ora isso é muito bonito e concerteza eu gostaria de usar um domain model puro, mas :

  1. O usuário aperta o botão de salvar … o que acontece ? O que é que se invoca ? concerteza não dá para invocar o objeto de dominio directamente

  2. Os dados nos objetos gráficos (inputs) viram objetos do dominio ? e nesse caso eles existem com a mesma “realidade” que os objetos que já estavam no dominio (prevalencia/persistencia) ? O que é um objecto de dominio “salvo” e um " a salvar" ?

  3. Onde ficam as validações ? controlo de tela , mensagens , transação , persistencia , etc … ?

Ou seja, é sério pensar que um sistema complexo , distribuido, com swing , multicamada, encapsulado, etc etc … pode ser baseado no dominio que não seja anémico. Se sim , como ? Que exemplos de aplicações reais existem que não usem um modelo anémico ?

Dar dá, estude Naked Objects que é uma abordagem que lida exatamente com isso.

De qualquer forma, arquitetura de Camadas existe exatamente para que ao clicar o botão existam direcionadores de fluxo que levam a mensagem até os objetos de domínio. A mensagem entra pela Camada de Apresentação e segue até a de Negócios, sofrendo transofmrações no caminho.

Os dados digitados pelo usuário ou obtidos de qualquer outra forma vão popular objetos de domínio. Antes, provavelmente, eles vão popular objetos da Camada de Apresentação (como os próprios formulários) e aí sim temos este tipod e objeto que representa um botão, um controle gráfico, etc.

Acho que a dificuldade que você está tendo é separar objetos em Camadas.

Um objeto deve obedecer a um contrato que lhe define as invariantes, pre e pos condições. O objeto eh responsavel por obedecer estas regras, se nao sao seguidas ele esta em estado invalido e deve prosseguir como tal (provavelmente lançando uma excecao).

Resumindo: validacao eh feita pelo objeto de negocios, por conveniencia ou desempenho pode-se replicar validacao na interface, o que geralmente eh feito em sistemas web.

Sim, o problema é exatamente que seus exemplos não estão separando as aplicações em Camadas.

Dos exemplos reais eu posso citar os sistemas de um dos maiores provedores de conteudo e Internet do Brasil, o software utilizado para comercializacao de commodities da maior empresa de energia eletrica do mundo, sistemas pre-pagos que provavelmente rodam na sua operadora de telefonia movel, gerencia da maior ferrovia do Brasil, sistemas de gestao de RH de uma das maiores empresas de hardware do mundo… soh o que lembro dentre os projetos que ja trabalhei.

E mais: trabalhar com Swing (ou qualquer coisa desktop) é ainda mais fácil do que web quando se trata de um domínio rico já que existe uma JVM no cliente.

Como falei, é uma questão de separar em Camadas.

excelente post pcalcado
tb tava em dúvida em relação a alguns aspectos assim

tem algum link pra artigos sobre isso?

http://www.fragmental.com.br/wiki

[quote=pcalcado][quote=sergiotaborda]

  1. O usuário aperta o botão de salvar … o que acontece ? O que é que se invoca ? concerteza não dá para invocar o objeto de dominio directamente
    [/quote]

Dar dá, estude Naked Objects que é uma abordagem que lida exatamente com isso.
[/quote]

Mas o problema é por ai mesmo. No fim parece que o objeto é tão naked(despido) que temos que o vestir com um monte de camadas…

O problema é esse. Se eu populo outros objetos que depois populam os de dominio isso vai dar no mesmo que usar TO pois esses objetos intermédios acabam sendo TO (mesmo que eles não pareçam TO, como um Map ou o Request)

Para que o Domain Model funcione ele tem que estar na camada de negocio, mas até lá tem um monte de logicas a serem feitas e os dados têm que transistar por elas. Isso leva à necessidade de TO, que é exactamente o que o anemic model não quer. Parece contraditório.
Num domain model verdadeiro os ppr objetos de modelo seriam os TO e eu poderia invocar seus métodos em qualquer ponto do sistema.
O exemplo classico é a validação. Eu poderia fazer ela no cliente (no caso de swing) mas uma exceção não é suficiente, eu preciso de um framework de validação para isso. Mais uma vez vestindo o objeto e retirando dele a capacidade de se validar (colocando numa annotation por exemplo)

O famoso controlo de tela se o campo A = x , desabilita B não pode ficar no objeto de dominio mas é uma regra de negocio. Então no fim o objeto de dominio não tem qualquer importância face à quantidade de outros objetos em outras camadas. Ou seja: não é possivel de apenas uma classe inferir todo o comportamento relativo à entidade de negocio que ela representa em todas as camadas do sistema.

Mas é exactamente ao separar em camadas que preciso dos TO e é exactamente ai que nasce o modelo anémico. Parece uma contradição. Não é ?

Não tem nenhum open source ?

Acho que você não entendeu. procure no Google sobre Naked Objects, é uma técnica de desenvolvimento apoiada por alguns frameworks como JMatter.

Não. Um TO é um objeto de transferência, ele possui responsabilidade de transferir dados de um canto para outro.

Um objeto de interface tem por responsabilidade lidar com input do usuário, não transferir dados. Um TO e um Request são muito diferentes, o Request representa a solicitação feita pelo usuário, que inclui dados e metadados.

Não há necessidade de TO. Por que haveria?

Os objetos da Camada de Aplicação recebem os dados ‘crus’ e os transformam em objetos que são passados para a Camada de Negócios invocando fluxos específicos (como chamar métodos em um Service Layer). Novamente: d~e uma cofnerida na literatura sobre camadas.

Você pode fazer isso, depende apenas de como modela suas camadas.

Como mencionei já trabalhei muito com Swing (não na construção do frontend mas na respsota aos eventos) e não vi necessidade de framework de validação. O controlados dos componentes de tela dispara métodos nos objetos de negócio, por exemplo tentando criar um objeto usuario. O objeto usuario, que é da Camada de Negócios, percebe que foi criado, digamos, sem um atributo login. Neste momento ele dispara uma exceção que é pega pelo controlador e tratada na interface. Esse é o padrão MVC original (sem estas aberrações web).

Como mencionado acima isto não é o que se espera de um padrão MVC. O Model vai gerar exceções que são tratadas pela View, a View é quem vai desabilitar campos, exibir alertas, etc. em resposta a estas solicitações.

Não há esta necessidade. Leia sobre Camadas. Mundo Java #15 tem um artigo sobre isso.

É difícil achar aplicativos J2EE como open-source, eu não lembro de nenhum caso notável.

Uma dúvida: voce trabalhava antes com Delphi, VB ou algo parecido?

[quote=pcalcado][quote=sergiotaborda]
Mas o problema é por ai mesmo. No fim parece que o objeto é tão naked(despido) que temos que o vestir com um monte de camadas…
[/quote]

Acho que você não entendeu. procure no Google sobre Naked Objects, é uma técnica de desenvolvimento apoiada por alguns frameworks como JMatter.
[/quote]
Cara, eu sei o que é…

Ora , e se eu crio o objeto na camada de view do swing, populo com os dados dos inputs, passo à camada de delegação do swing, que serializa o objecto e passa ao servidor, que desserializa e passa à camada de serviços que passa à camada de domino e à de persistência, não é transferência que eu estou fazendo ? Se não é, o que é então ?

Eu discordo disso. Mas o ponto não é esse. O ponto é que em algum lugar do sistema eu preciso condensar inputs num objeto só. Seja qual for e implemente o padrão que for esse objecto não é um objeto de dominio.
Ele é um objecto auxiliar, um objeto de framework. Ora os objetos auxiliares são exactamente o que o Anemic Domain Model (ADM) não quer ter.
Então parece-me que existe uma contradição entre dizer que ADM é ruim e que devemos ter objetos de dominio com todas as regras dentro deles quando isso não é compatível com sistemas distribuídos.

Você afirma que sim. Ok. Então por favor me dê um exemplo de um objecto de dominio que vc tenha criado, que siga o padrão Domain Model e não o ADM.

Vc não viu exatamente porque não trabalhou com o front end. Dê uma olhada no JGodies Validation para ver do que estou falando. Não basta dizer que está inválido, tem que dizer como, onde , porquê e como resolver. Essa informação está normalmente no validador e no help e não no objeto de domínio.

Que seja. O uso de MVC apenas reforça o que eu disse: não é o objeto do domínio que contém a regra daquilo que acontece na tela.

Básicamente a minha dúvida é saber se definindo uma classe com todos os atributos e métodos, junto com anotações especiais eu a posso usar em toda e qualquer camada da aplicação. Exemplo: A camada de validação usa as anotações de valdiação, a camada de persistencia usa as anotações de persistencia, etc etc… apenas a camada de negócio usa os métodos da classe que “fazem alguma coisa”.

Não. Nunca trabalhei com isso. Eu programei com eles, especialmente com VB e fiz alguma coisa - básicamente manutenção de programas já existentes - mas não foi do meu agrado e por isso mudei para Java por isso (entre outras razões). Mas o Java é uma tecnologia e por isso é necessário cria/usar padrões/frameworks para facilitar as coisas. Eu tenho ouvido falar do ADM e concordo com a ideia, mas não me parece que seja aplicável a uma aplicação séria. Por exemplo BPM é um modelos anémico logo à partida e é um modelo muito mais Business-friendly que Domain Model. Domain Model não se dá bem com aplicações destribuidas. É isso que quero saber. Se sim , ou não e em que medida.

O uso de um Domain Model independe da topologia da tua aplicação. Ele simplesmente serve para modelar de maneira mais clara e intuitiva os conceitos do negócio.

Todo sistema vai ter muitos objetos auxiliares e não relacionados ao modelo que fazer o plumbing necessário. O uso de DDM diz respeito a parte do sistema que cuida das regras do negócio e não tem o menor relacionamento com a camadas de infra-estrutura.

O sistema pode sim ser distribuido, precisar DTOs e tudo mais, mantendo um domain model na parte que cabe dele. Outra coisa, em algumas situações é possivel e interessante mapear coisas como validação e workflows como objetos de domínio. DDD diz muito a respeito da comunicação com o cliente, por exemplo, se ele quer discutir sobre “os cenários no qual XXX é pertinente”, o desenvolvedor acaba por modelar isso como um objeto do modelo, apesar de ser só validação.

Tocando no assunto dos TO, eu sempre tive dúvidas de como fazer a comunicação de um cliente swing com um ejb de fachada, por exemplo, sem o uso de TO. Isso é possível de ser feito? O uso de TOs transforma o meu modelo num Anemic Domain Model?

[quote=louds]O uso de um Domain Model independe da topologia da tua aplicação. Ele simplesmente serve para modelar de maneira mais clara e intuitiva os conceitos do negócio.

Todo sistema vai ter muitos objetos auxiliares e não relacionados ao modelo que fazer o plumbing necessário. O uso de DDM diz respeito a parte do sistema que cuida das regras do negócio e não tem o menor relacionamento com a camadas de infra-estrutura.
[/quote]

Ah! era isso que eu queria ler. Essa foi tb a conclusão a que cheguei.
Mas nesse caso como eu faria a associação dos TO com os Objetos de Dominio. Exemplos ? …

Sim, e nesse caso você deve utilizar um DTO (na maioria das vezes), ninguém nunca disse o contrário.

Qual o problema do objeto do framework (Controller, por exemplo) instanciar e enviar apra a Camada de Negocios um objeto de dominio? o que ele nao faz é processar regras de negócio.

Para este tipo de coisa existe o apdrão DTO, leia a descrição no POEAA.

Leia os artigos em:
http://fragmental.com.br/wiki

Sérgio: a View sabe reagir ao Modelo, isso é o feijão-com-arroz do MVC. Se o modelo lança uma DataInvalidaException a view deve saber reagir a isso.

O que acotnece na tela está na Camada de Apresentação, que não é onde residem os objetos de negócio (eles são de domínio mas de um outro domínio, não o de negócios).

Você simplesmente não deveria fazer isso.

De qualquer modo fica muito difícil continuar essa discussão de você não ler sobre:

  • Camadas
  • DTOs
  • Naked Objects

Porque suas dúvidas são respondidas na bibliografia. Recomendo a laitura do POEAA, de Martin Fowler e dos artigos e apresentações do link que passei acima.

[quote=sergiotaborda]
Ah! era isso que eu queria ler. Essa foi tb a conclusão a que cheguei.
Mas nesse caso como eu faria a associação dos TO com os Objetos de Dominio. Exemplos ? …[/quote]

http://www.fragmental.com.br/files/presentations/riojug/Arquitetura_de_Camadas_em_JEE_PDF.zip

Sim, e nesse caso você deve utilizar um DTO (na maioria das vezes), ninguém nunca disse o contrário.
[/quote]
[/quote]

Pois isto
diz exactamente o contrário. E essa imagem foi tirada daqui http://fragmental.com.br/wiki/index.php?title=Evitando_VOs_e_BOs
Que é o site que vc recomenda tanto que eu leia.

O que é difícil é vc deixar de me tratar como seu eu tivesse 17 anos e prestar mais atenção na mensagem e menos no mensageiro.

[quote]
Porque suas dúvidas são respondidas na bibliografia. Recomendo a laitura do POEAA, de Martin Fowler e dos artigos e apresentações do link que passei acima.[/quote]

A verdade é que não são. Exactamente por eu ter lido sobre esses assuntos e essa “bibliografia” que eu tenho cheguei na conclusão que um sistema destribuido é anémico por natureza. Isto porque ele sempre seque aquele esquema da imagem acima , mesmo quando vc tiver verdadeiro objetos de dominio continua tendo objetos como aqueles que são basiacamente DTO e Service Layer.

Quanto ao PDF é muito bonito mas não tem os exemplo que eu pedi.

Calma sergio! O pcalcado só está ajudando. Se tu lesse o artigo direito veria que essa figura se refere ao Anemic Domain Model que o artigo mostra como problema e não como solução!

Se você tivesse perdido 15 minutos e lido o artigo veria que isso é um anti-exemplo. O artigo fala exatamente sobre como você deveria evitar este tipo de coisa, eu sei o que está escrito nele porque fui eu quem escreveu e recomendei tanto a leitura porque escrevi este texto e os outros exatamente para não precisar repetir estas coisas em todo santo post no GUJ.

A sua mensagem anterior só mostra que eu me enganei ao tentar conversar como você como alguém que quer aprender e ensinar algo. Você nem sequer leu o artigo (que se chama “Evitando VOs e BOs”). Logo abaixo desta figura ele fala sobre os problemas deste modelo.

O PDF tem o exemplo na parte sobre DTO (que é o mesmo do Fowler, está bem pequeno, é verdade, mas eu poderia te indicar outro material se você tivesse um mínimo de educação e interesse em procurar algo e não apenas expôr suas idéias que contradizem tudo que você diz que leu. Aliás até o texto de onde você tirou esta figura também tem um exemplo gráfico sobre DTO e uma explicação textual.

Bom, eu desisto de conversar com você, com a consciência limpa de ter tentado mesmo após tantas besteiras e tantos ataques em tantas outras trheads (é só ver o histórico do usuário acima).

É mais que óbvio que você quer concluir suas coisas partindo da sua própria opinião e se recusa a procurar mais sobre o assunto. Se alguém quiser conversar sobre este tema sinta-se a vontade, eu apenas não respondo mais ao colega acima nem neste tópico nem em qualquer outro.

[quote=mutano]Calma sergio! O pcalcado só está ajudando. Se tu lesse o artigo direito veria que essa figura se refere ao Anemic Domain Model que o artigo mostra como problema e não como solução!
[/quote]

Exactamente. O problema qual seria ? Ter dois tipos de objetos : os TO (VO,DTO, chamem como quiserem) e aquilo que o artigo chama de BusinessObject. Eu sei perfeitamente que isto não é um Domain Model porque um Domain model é a fusão daqueles dois objetos.

Ora , então a logica é: se TO é sinónimo de ADM , retirese o TO e deixe fica só o Objecto de Dominio (OD). O que o pcalcado falou é que pode usar TO que isso não contraria / impede usar OD. Mas o artigo e o prórpio principio do Anemic Domain Model diz exatamente o contrário. TO não existem num Domaim Model verdadeiro, só existem OD.

Mas o pcalcado não partilha desta opinião e falou que sim pode usar TO o que é uma contradição.
Eu partilho a opinião do louds que pode usar os dois e pedi exemplos de como encaixar os dois. MAS se eu usar essa forma, eu estarei automáticamente usando um Anemic Domaim Model. Nem o artigo, nem o Martin , nem ninguém até agora explicou como se usa Domain Model sem TO num ambiente destribuido. A minha opinião é que isso simplesmente não é possivel porque sempre teremos camadas inevitavelmente sempre teremos TO e portanto inevitavelmente caímos no ADM.

Olá, estou bem atento a esta thread, pois OO é algo que sempre me interessa… Porém ainda não entendi uma coisa: por exemplo, eu tenho um formulário de cadastro de disciplinas, o usuário entra com os dados da nova disciplina, quando ele clica no botão salvar, ele salvará estes dados em um objeto, será tratado e só então transferido ao domain model? É isto?

Ainda nãi está claro para mim.

Alguém possui exemplos web e/ou desktop para que eu possa entender melhor?

Sérgio, você tem certeza que leu o artigo do Fowler sobre DTOs? Por que lá está super claro como você faz para transformar entre o DTO e os objetos de domínio.

Se o idioma for problema, o tradutor do google deve dar conta, já que ele usa um ingles muito regular.

Inclusive, ele recomenda usar outro pattern do PEAA para resolver isso.

[quote=sergiotaborda] Nem o artigo, nem o Martin , nem ninguém até agora explicou como se usa Domain Model sem TO num ambiente destribuido. A minha opinião é que isso simplesmente não é possivel porque sempre teremos camadas inevitavelmente sempre teremos TO e portanto inevitavelmente caímos no ADM.
[/quote]

Você leu isso sério?

Nessa sua aplicação ultra complexa aí que talvez pudesse ser feita de forma bem mais simples mas por algum motivo tem que ser distrbuída, você poderia usar DTOs pra levar os dados do swing para o servidor chegando lá(na camada de serviços) você instancia um objeto de domínio e executa metódos de negócios que fazem parte única e exclusivamente dos seus objetos de domínio.
Você tem DTOs, apenas porque quer fazer sua aplicação distribuída mas seus objetos de domínio tem seus atributos e suas operações.

[quote=sergiotaborda]Nem o artigo, nem o Martin , nem ninguém até agora explicou como se usa Domain Model sem TO num ambiente destribuido. A minha opinião é que isso simplesmente não é possivel porque sempre teremos camadas inevitavelmente sempre teremos TO e portanto inevitavelmente caímos no ADM.
[/quote]

Concordo na parte que de qualquer jeito vc cai num ADM. Discordo na parte onde vc fala que o Martin não explicou. Ele explicou… :wink:

[quote=louds]Se o idioma for problema, o tradutor do google deve dar conta, já que ele usa um ingles muito regular.
[/quote]

Comentário desnecessário.