Quando usei o IoC Container no meu último projeto, acabei com entidades anêmicas e com a maior parte da minha lógica de negócios no Stateless Services.
Eu já vi projetos escritos por outros desenvolvedores que utilizam "Inversion of Control" e eles são sempre "Anêmicos".
Como o "Modelo de Domínio Anêmico" é antipadrão, é possível usar IoC e Rich Domain? São alguns bons exemplos, projetos de código aberto que fazem isso?
dependency-injection
Mag20
fonte
fonte
Respostas:
Para iniciantes: DI e IoC não são sinônimos. Sinto muito, mas devo salientar isso (parece-me que você pensa que são).
Quanto à sua pergunta ... Bem, injeção de dependência é apenas uma ferramenta. Como você vai usar essa ferramenta é uma coisa completamente separada. Existem também outras ferramentas (padrões de design) que podem resultar no problema. Por exemplo, acho que a ampla adoção do padrão MVC é um dos principais ingredientes para formar o antipadrão do Modelo de Domínio Anêmico: Controladores (em aplicativos mais simples, em aplicativos mais complicados que seriam Camada de Serviço adicional) assumem a responsabilidade de validar regras de negócios , aplicando-as e transformando entidades de banco de dados em algo útil, enquanto a Camada de negócios se transforma em uma Camada de acesso a dados simples que é ORM simples com mapeamento individual para entidades de banco de dados.
Certamente, é assim que você cria seu aplicativo - você pode criar um Modelo de Domínio correto, se quiser, e todos esses IoC, DI, MVC não o impedem. O que poderia parar você é sua equipe. De alguma forma, você precisa convencê-los a usar o caminho certo e pode ser difícil, pois muitos desenvolvedores de software não possuem um forte histórico arquitetural.
fonte
A maioria dos aplicativos (se não todos) é uma mistura de preocupações de infraestrutura e domínio. Quando você alcança um certo nível de complexidade, facilita o gerenciamento se o domínio estiver separado da infraestrutura, para que seja mais fácil raciocinar e possa evoluir independentemente.
É claro que o modelo de domínio ainda precisa se comunicar com o restante do sistema e, geralmente, isso ocorrerá com serviços sem estado (que fazem parte do domínio) que têm problemas de infraestrutura (como acesso ao banco de dados) injetados neles. O uso de um contêiner de IoC não remove essa dependência, ele move sua configuração para uma área separada - novamente facilitando o raciocínio e a manutenção.
As entidades estão armazenando o estado e devem ser responsáveis pelas regras de negócios. Se seus serviços estão aplicando todos os invariantes e outras regras de negócios, é provável que a lógica esteja no lugar errado.
Agora, se você tem a lógica nos lugares certos e ainda assim acabou com serviços que não passam de invólucros em torno de coisas e entidades de infraestrutura que são apenas itens de propriedade, é muito provável que o domínio não seja complexo o suficiente para justificar a sobrecarga de seu próprio modelo. Qualquer coisa que você ler sobre o DDD conterá um aviso de isenção de responsabilidade que realmente é destinado apenas a domínios complexos, mas isso parece ser esquecido com muita frequência.
fonte
Vá para a fonte. Comece com a peça de Fowler sobre os modelos de domínio anêmico . Ele refere o Domain Driven Design de Eric Evan como um exemplo de boas práticas. O código fonte para isso está aqui . Baixe.
Observe que ele usa Inversion of Control (procure por @Autowired) e possui classes de serviço (BookingService) e classes de "processo de negócios" (por exemplo, ItineraryUpdater).
O artigo original de Fowler inicia a trilha para o exemplo que você está procurando.
fonte
VoyageRepositoryHibernate
classe, que foi colocada na camada de infraestrutura, mas na verdade depende da camada de domínio.save(foo)
com código que está sujeito a alterações quando o modelo de domínio é alterado (por exemplo, se um novo atributo é adicionado aMyDomainObject
), ele deve (por definição) pertencer à camada de domínio; caso contrário, você não poderá mais falar em ter "camadas".Suponho que você queira dizer DI em vez de IoC, e o projeto em que você trabalhou usa um contêiner DI como Spring. A IoC possui dois sabores principais: padrão DI e Locator. Não vejo por que o padrão Locator deve ser um problema, então vamos nos concentrar no DI.
Não acho que seja possível, ou pelo menos seria muito impraticável. O principal aspecto dos contêineres DI é que eles controlam a criação de objetos quando os injetam em outros ("objetos gerenciados"). O conjunto de objetos gerenciados ativos quando os projetos são executados é independente de quais itens de domínio existem no seu projeto, mas depende de como os objetos são conectados e quais escopos (singleton, protótipo) são atribuídos a eles.
É por isso que você não deseja permitir que o contêiner de DI gerencie seus objetos de domínio. Mas se você criar objetos manualmente (com o novo), não poderá injetar outros objetos nos objetos do seu domínio. (Deixando possíveis soluções alternativas com a fiação manual de lado.) Como você precisa dessas injeções para substituir implementações por outras, não é possível substituir a funcionalidade de objetos de domínio avançado usando DI. Portanto, você não desejará colocar a funcionalidade em objetos de domínio ou perderá os recursos do DI.
Não vejo como poderia funcionar um contêiner de DI hipotético que não gerencia seus objetos, e nenhuma das implementações existentes permite isso. Portanto, é justo afirmar que o DI depende do gerenciamento de objetos. Portanto, sempre tentará que você divida objetos em potencial do Rich Domain em uma classe anêmica e em uma ou várias classes de scripts de transação.
fonte