Estou definindo meus primeiros passos no design orientado a domínio, comprei o livro azul e tudo, e me vejo vendo três maneiras de implementar uma certa solução. Para constar: não estou usando CQRS ou Event Sourcing.
Digamos que uma solicitação do usuário entre na camada de serviço do aplicativo. A lógica de negócios para essa solicitação (por qualquer motivo) é separada em um método em uma entidade e um método em um serviço de domínio. Como devo chamar esses métodos?
As opções que reuni até agora são:
- Deixe o serviço de aplicativo chamar os dois métodos
- Use a injeção de método / despacho duplo para injetar o serviço de domínio na entidade, deixando que a entidade faça o que é necessário e depois chame o método do serviço de domínio (ou vice-versa, deixando o serviço de domínio chamar o método na entidade)
- Aumente um evento de domínio no método de entidade, cujo manipulador chama o serviço de domínio. (Os tipos de eventos de domínio dos quais estou falando são: http://www.udidahan.com/2009/06/14/domain-events-salvation/ )
Eu acho que tudo isso é viável, mas não consigo escolher entre eles. Estou pensando nisso há muito tempo e cheguei a um ponto em que não vejo mais as diferenças semânticas entre os três. Você conhece algumas diretrizes quando usar o quê?
Respostas:
O serviço de aplicativo geralmente é um ótimo ponto de partida para isso, no entanto, você deve sempre tentar mudar o comportamento o mais próximo possível da entidade. O serviço de aplicativo desempenha uma função de orquestração e prepara o cenário para a execução do comportamento do domínio e, como tal, fornece todas as dependências necessárias. No entanto, quando possível, ele deve delegar o comportamento ao modelo de domínio.
Essa é uma abordagem melhor, porque mais do comportamento é delegado à entidade ou serviço de domínio. A maneira mais dissociada de implementar isso é fazer com que uma entidade expresse uma dependência de um serviço como parâmetro do método que fornece o comportamento em questão.
O padrão de evento do domínio, conforme explicado por Udi e também pelo próprio Evans, é bastante versátil e pode ser aplicado em uma variedade de cenários. No entanto, existem algumas complicações. Primeiro, você deve ter o escopo adequado no editor de eventos do domínio. Na maioria das vezes, os manipuladores de eventos do domínio terão dependências e, se você estiver usando um contêiner de IoC, precisará garantir que as instâncias adequadas sejam injetadas. Por exemplo, em um aplicativo Web, o
[ThreadStatic]
atributo é problemático para o escopo. Outra complexidade é a das fronteiras transcricionais. É necessário levar em consideração as transações, porque se uma entidade gerar um evento de domínio, mas um commit subsequente no banco de dados falhar, todos os manipuladores de eventos do domínio precisarão de uma maneira de reverter, caso contrário, você acabará gerando um evento inválido. Se, no entanto, você tiver coberto essas bases, os eventos do domínio serão um ótimo padrão para encapsular a lógica do domínio dentro das próprias entidades.A diferença entre a abordagem 2 e 3 depende do caso de uso. Um evento de domínio se aplica quando você deseja chamar comportamentos adicionais em resposta a um evento, que está no passado . Essa é uma restrição importante, pois o manipulador de eventos do domínio não pode afetar o comportamento da entidade. Por outro lado, com a abordagem 2, o serviço injetado pode afetar o comportamento porque é declarado uma dependência para esse comportamento específico.
fonte