dom 02 fevereiro 2014
Aos que ainda não conhecem o conceito de Domain Driven Design (DDD), sugiro que busquem conhecer o quanto antes (pode começar pela indicação de livro no final do post). O objetivo desse post não é explicar o DDD (talvez em um próximo post), mas sim tentar ajudar a desmistificar uma dúvida que pode ser recorrente dos que começam a desenvolver software orientado ao domínio.
A base do DDD diz que o desenvolvimento de uma solução de software deve ser feito respeitando-se algumas camadas para a organização da solução:
Dentro da Camada de Domínio, onde realmente o DDD se foca, há ainda mais alguns conceitos envolvidos:
Essa foi uma apresentação simplista e rápida dos principais conceitos envolvidos. Agora, quando alguns desenvolvedores se deparam com todo esse novo universo de organização pode se perguntar onde, de fato, implementar suas lógicas de negócio. Lembrando que lógica do negócio é diferente da implementação do fluxo da aplicação (tarefas ou interação com outros sistemas, por exemplo).
Se considerar somente os padrões da camada de domínio pode-se muito facilmente concluir que a implementação de um software segundo esses padrões acarretará o anti-pattern Modelo de Domínio Anêmico. Nesse anti-pattern as entidades possuem somente estados (atributos) e nenhum comportamento (métodos). Nas palavras do Martin Fowler bags of getters and setters. Nesse modelo as entidades não possuem quaisquer lógicas de negócio, essas ficam abrigadas em classes estritamente de serviços, onde a sua responsabilidade é fornecer as lógicas de negócio.
Dentre outros problemas, melhor apresentados no artigo do Fowler, com o Modelo de Domínio Anêmico corre-se um risco eminete de se perder os princípios da orientação a objetos e tornar as classes de serviços meras aberrações procedurais. Infortunadamente os problemas práticos dessa abordagem só são percebidos no decorrer da manutenção do software.
Assim sendo, de maneira alguma o DDD prevê o Modelo Anêmico, muito pelo contrário, com o DDD as Entities não são restritas a estados. Da mesma forma que um bom design de projeto orientado a objetos, um projeto DDD deve detectar as entidades do domínio e os comportamentos das entidades de domínio. Se uma entidade possui seus atributos e comportamentos bem definidos, não há porquê separá-los na implementação, de forma que uma entidade no DDD pode (e deve) possuir, além de seus atributos, seus comportamentos com as regras de negócios envolvidas.
Porém não deve-se com isso fazer com que a implementação do domínio distorça o domínio real. Ao se analisar os problemas a serem resolvidos pela implementação e tentar definir os objetos do modelo, muito facilmente haverão alguns aspectos e comportamentos que não serão facilmente associados a nenhum objeto do modelo. Para as ações "orfãs" de objetos do modelo é que existem os Services. Um exemplo básico é a operação de transferência de dinheiro de uma conta para outra. A ação (método) de transferência pertence à conta de origem ou à conta de destino? Aparentemente não faz sentido em nenhuma das duas, não é?
Quando esse tipo de comportamento é detectado na análise da solução, a melhor prática é implementá-lo como um serviço. A principal resposabilidade de um Serviço é fornecer funcionalidades, que não são de responsabilidade direta de qualquer objeto do modelo, para os próprios objetos do modelo. Vale atentar ao fato de que, classes de serviço, como quaisquer outras da solução, devem seguir obrigatoriamente, os princípios da orientação a objetos.
Respondendo a pergunta do título do post: se a regra de negócio for explicitamente parte de um comportamento de uma entidade do modelo, então a regra deve ser implementada no comportamento da entidade. Agora, se a regra de negócio não pertence claramente a qualquer objeto do modelo, então deve-se estudar e analisar muito bem a criação de um Serviço que ofereça determinada funcionalidade que implemente a devida regra de negócio.
Links úteis:
Encontrou algum erro, gostaria de compartilhar algum comentário comigo ou fazer qualquer sugestão? Entre em contato através de alguma das formas listadas na página de contato.