DDD com ORM para onde deve ir a lógica de negócios?


10

Eu usei uma ferramenta MDA (arquitetura orientada a modelo) no passado, onde modelamos via UML e isso gerou as entidades de negócios (nosso modelo de domínio) e o ORM (mapeamento etc.) entre outras coisas.

Muitos códigos e serviços de negócios que trabalham no domínio faziam parte do modelo e nossos repositórios estavam retornando as entidades de negócios (portanto, seria impossível mudar para outro ORM (não o que desejávamos)).

No entanto, agora estou iniciando um projeto e quero pensar em termos de DDD.

Até agora, parece que eu coloquei minha lógica de negócios no meu modelo de domínio e, através de repositórios, eu trabalharia com o ORM (que sempre que eu escolher). No entanto, se eu quisesse continuar usando a ferramenta MDA para a parte ORM do aplicativo, o modelo criado aqui seria muito anêmico (ou seja, não conteria nenhuma lógica comercial). Da mesma forma, se eu usasse o Entity Framework (.net) ou NHibernate para o meu ORM, também seria um modelo anêmico. Não sei onde você colocaria a lógica de negócios se eu apenas usasse o NHibernate.

Estou correto ao pensar dessa maneira, em outras palavras, com DDD toda a lógica de negócios no domínio e apenas usar o ORM para persistência através de repositórios?

Respostas:


12

portanto, seria impossível mudar para outro ORM (não que quiséssemos)).

Isso parece errado. Uma grande vantagem do padrão de repositório é que você oculta a lógica de acesso a dados e é facilmente trocável.

Até agora, parece que eu coloquei minha lógica de negócios no meu modelo de domínio e, através de repositórios, eu trabalharia com o ORM (o que quer que eu tenha escolhido). No entanto, se eu quisesse continuar usando a ferramenta MDA para a parte ORM do aplicativo, o modelo criado aqui seria muito anêmico (ou seja, não conteria nenhuma lógica comercial). Da mesma forma, se eu usasse o Entity Framework (.net) ou NHibernate para o meu ORM, também seria um modelo anêmico. Não sei onde você colocaria a lógica de negócios se eu apenas usasse o NHibernate.

Um modelo de domínio anêmico é considerado uma prática ruim por muitos, por exemplo, por Martin Fowler. Você deve evitar esse design, porque esse modelo leva a técnicas de design procedurais, em vez de um bom design orientado a objetos. Você tem classes de dados e classes de gerente / processamento, o que significa que você separou estado e comportamento. Mas um objeto realmente deve ser "estado e comportamento".

O NHibernate faz um ótimo trabalho na ignorância da persistência. Você pode ocultar os detalhes do mapeamento em XML ou com o FluentNHibernate e apenas escrever POCOs simples. É muito fácil criar um modelo de domínio avançado com o NHibernate. Eu acho que você pode fazer isso com a estrutura de entidades e a ferramenta MDA também. Desde que essa ferramenta produza classes parciais, você poderá estender o código gerado com bastante facilidade, sem precisar se preocupar que uma nova geração possa destruir seu código escrito pelo usuário.

Para encurtar esta longa história. Quando você usa o NHibernate, nada, repito nada , impede você de adotar um modelo de domínio rico. Eu recomendo usá-lo com FluentNHibernate e mapear manualmente. O código de mapeamento leva apenas 5 a 10 minutos para gravar. Suponho que o mesmo se aplica à estrutura da entidade e que suas ferramentas criem pelo menos classes parciais que são facilmente extensíveis.

Estou correto ao pensar dessa maneira, em outras palavras, com DDD toda a lógica de negócios no domínio e apenas usar o ORM para persistência através de repositórios?

Para a maior parte você está correto. Você deve ter um modelo de domínio avançado. Especialmente quando as coisas se tornam cada vez mais complexas, é mais fácil manter e estender quando você as desenhou corretamente. Mas lembre-se de que o DDD também conhece os Serviços (Camada de Domínio e Camada de Aplicativo) para implementar a lógica de negócios e Fábricas para encapsular a lógica criacional.

Eu também tendem a diferenciar lógica de negócios em lógica de domínio e lógica de negócios de aplicativo real. A lógica do domínio é como o domínio interage e se comporta enquanto a lógica do aplicativo, que é uma camada completamente diferente, encapsula como o domínio é usado para o caso de uso / aplicativo específico. Muitas vezes, tenho que atualizar o modelo de domínio para dar suporte a casos de uso específicos e torná-lo mais poderoso.


2
+1: Eu também separo a camada lógica do domínio da camada lógica do aplicativo. Coloquei todo o material do ORM e do banco de dados na camada lógica do domínio. A camada lógica do aplicativo não sabe nada sobre o ORM, transações e tudo mais: apenas vê classes de lógica de negócios e chama seus métodos. Acho essa abordagem muito eficaz por ter uma camada lógica de aplicativo mais simples e limpa.
Giorgio

@ Falcon: Obrigado pela informação. Quando mencionei o modelo anêmico, o que eu quis dizer foi que, se eu criar um domínio usando DDD, uma versão dos meus repositórios seria a versão mda, onde eu apenas moveria minhas entidades para as entidades mda (ou seja, modelo anêmico) e as persistiria. em transações etc. Isso seria bom? Duvido que usarei a ferramenta MDA, mas apenas tentando entender como eu poderia, se quisesse. Isso soa certo?
JD01

@ JD01: Eu não entendo bem você, mas parece que você deseja transformar entidades de modelo de domínio para poder persistir com facilidade. É como usar DTOs e o automapper (google it) pode ser uma ferramenta útil para essa tarefa. Essa abordagem não interfere necessariamente nas melhores práticas de DDD. Afinal, os repositórios também devem ocultar a lógica de acesso a dados. Você pode transformar seus objetos de negócios nos bastidores em DTOs MDA e persistir, e o usuário da API nem perceberia. Eu acho que está bem.
Falcon

11
@ JD01: Sugiro que você dê uma olhada no link a seguir para ver quantos java Enterprise fazem isso. Eles basicamente têm um DAO, um DTO e um BO (objeto de negócios). Para mim, são muitas camadas, mas o design está bem. java.sun.com/blueprints/corej2eepatterns/Patterns/…
Falcon

@Falcon: Sim, eu estava pensando que as DTOs eram meus objetos MDA, não que eu fosse assim. Apenas entendendo o que cada parte dos players de DDD d0. Obrigado mais uma vez.
JD01

3

No entanto, se eu quisesse continuar usando a ferramenta MDA para a parte ORM do aplicativo, o modelo criado aqui seria muito anêmico (ou seja, não conteria nenhuma lógica comercial).

Não sei qual ferramenta MDA você está usando, mas as que trabalhei sempre criam classes parciais para que você fique livre para completá-las com a lógica de negócios que desejar.

No entanto, acho que as ferramentas MDA são um pouco menos apropriadas em um contexto DDD que os ORMs, porque a geração de código geralmente tende a produzir classes confusas com ruído específico da ferramenta, em vez das entidades de domínio claramente expressas e otimizadas que esperamos. Na verdade, o que você geralmente obtém é uma mistura de dados de domínio, lógica de persistência, lógica de validação de restrições ... e não sei se há uma maneira de separar essas preocupações com a maioria das ferramentas MDA.

E, é claro, você não pode tocar no código gerado, exceto por meio de classes parciais, o que significa que não pode eliminar o possível comportamento anti-DDD que seria integrado. Isso é problemático em uma abordagem em que você deseja impor barreiras estritas entre os agregados e adaptar os relacionamentos entre suas entidades perfeitamente. O tempo de construção em um ambiente de integração contínua também pode sofrer com a etapa adicional de geração de código.

Além disso, acho que o Falcon praticamente disse tudo - absolutamente nada nas ferramentas ORM ou MDA impede que você tenha entidades de domínio avançadas.


Olá, estou usando o ECO (objetos principais da empresa) de compatibleobjects.com e é exatamente como você o descreveu.
JD01

1

O que faço na minha equipe é modelar meu objeto, domínio e adicionar minha lógica de negócios ao mesmo tempo. Eu não uso o Model Driven Development que geraria um código a partir de um modelo, mas preferiria a abordagem de anotação. Quero dizer que, no nível do objeto, dentro do diagrama de classes, adiciono estereótipos ORM. Isso adicionará anotações de persistência diretamente no código que são compatíveis com EJB3 / hibernate. A criação do banco de dados é feita pelo Hibernate e certamente não pelos modelos UML. Isso é muito melhor porque se o código for alterado e as anotações adicionadas não forem exatamente o que o especialista em hibernação, ele poderá alterar, mas o modelo ainda será bom. Também posso alterar meus requisitos e meu modelo de domínio ainda está ok.

Os desenvolvedores podem adicionar lógica de negócios dentro de cada método e adicionar um comentário, também posso modelar e adicionar restrições. Por exemplo, as vendas devem ter mais de 50k, se não, etc. UML realmente interessante e flexível.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.