Domain-Driven Design, do início ao código

Quando se fala em Domain-Driven Design (DDD), logo se pensa no modelo arquitetural, nos building blocks do DDD e nos design patterns relacionados.
E é claro que nós somos apaixonados por isso, afinal somos desenvolvedores! ❤️
Porém, para trabalhar com DDD precisamos desenvolver mais alguns skills, como aprender a modelar domínios de forma efetiva, e, para isso, precisamos nos tornar o que o Eric Evans chama de Knowledge Crunchers — processadores de conhecimento — alguém preparado para receber, filtrar e organizar uma avalanche de informação.
Domain-Driven Design é, antes de tudo, comunicação. No DDD modelagem e implementação andam juntas.
Especialistas do domínio (usuários, analistas e outros especialistas da área), juntamente com os desenvolvedores e arquitetos trabalham de mãos dadas com um objetivo em comum: construir software guiado pelo domínio para atender as necessidades do cliente.
Para fazer isso, em primeiro lugar, é necessário que todos usem uma linguagem em comum e que não haja tradução na comunicação entre os membros do time.
O time desenvolve, portanto, uma linguagem ubíqua (geral e universal) que expressa o conhecimento dos especialistas de negócio para o modelo de domínio (para o código).
Devo guiar meu projeto pelo domínio, mas o que exatamente é o domínio?

O domínio de um software são as atividades desempenhadas pelo usuário e a área de interesse destes.
O domínio pode ser tão complexo quanto os processos e dados que ele compreende.
E o modelo?
Um modelo é, de acordo com Evans (2004, p. 2) “uma simplificação. É uma interpretação da realidade que abstrai os aspectos relevantes para resolver o problema em questão e ignorar detalhes alheios a isto” (tradução livre).
Com um modelo conseguimos:
- Abstrair a complexidade do negócio através de uma representação simplificada do mesmo — um modelo.
- O modelo serve como algo comum e palpável a todos os membros do time, que, junto com a linguagem ubíqua, permite que todos possam participar ativamente da construção progressiva do mesmo.
- O modelo (desde que feito corretamente) garante que aquilo que está sendo especificado é o que está sendo implementado.
- O modelo é o meio de comunicação usado pelo time. Graças ao vínculo entre o modelo e a implementação, os desenvolvedores podem falar na linguagem do software ao comunicarem-se com os especialistas do domínio (sem ter que traduzir a mensagem).
- O modelo é o conhecimento destilado — é o modo como o time concorda em estruturar o conhecimento extraído do domínio.
EVANS (2004)
O modelo é evolutivo: A cada iteração entre especialistas de domínio e a equipe técnica, o modelo se torna mais profundo e expressivo, mais rico, e os desenvolvedores transferem essa fonte de valor para o software.
Assim, o modelo vai sendo gradualmente enriquecido com o expertise dos especialistas do domínio destilado pelos desenvolvedores, fazendo com que o time ganhe cada vez mais insight sobre o negócio e que esse conhecimento seja transferido para o modelo (para o código) através dos blocos de construção do DDD.
Quando novas regras de negócio são adicionadas e/ou regras existentes são alteradas ou removidas, a implementação é refatorada para refletir essas alterações do modelo no código.
No final, o modelo (que em última instância será o software) vai expressar com riqueza de conhecimento o negócio.
Como explica Evans (2004, p. 23) “DDD coloca um monte de conhecimento no modelo que reflete profundamente o domínio.
Isso só é possível através da colaboração entre quem conhece o domínio e quem sabe criar software. 🤝
E como o desenvolvimento é iterativo, essa colaboração continua durante todo o andamento do projeto.”
Ou seja, o Domain-Driven Design nos leva a construir softwares guiados pelo conhecimento e modelagem do negócio antes de qualquer apelo por tecnologia.
Obviamente para que possamos implementar o modelo de domínio com sucesso, precisamos de engenharia. 😎
E, por isso, o DDD nos conduz através dos seus blocos de construção a utilizar alguns princípios de arquitetura e design patterns consagrados, entre eles destaco:
- Isolamento do domínio com arquitetura em camadas.
- Representação do modelo através de artefatos de software bem definidos (entities, value objects, services, factories, repositories, specs, modules, etc).
- Gerenciamento do ciclo de vida de objetos do domínio com aggregates.
Demonstrarei na prática cada um deles nos próximos artigos desta série sobre Domain-Driven Design. Mas agora voltemos à teoria, pois é necessário antes ter um bom fundamento se quisermos construir um modelo realmente efetivo.
Os 5 ingredientes de um modelo efetivo:
- Vincular o modelo com a implementação: esse vínculo é feito desde o início, quando o modelo ainda é primitivo e será mantido até o fim. Esse vínculo é profundo, a implementação deve refletir 100% o modelo.
- Cultivar uma linguagem baseada no modelo: no início será necessário que os desenvolvedores e os domain experts entendam cada um os termos do outro, mas depois ambos falarão a mesma linguagem, organizando as sentenças da comunicação numa estrutura consistente com o modelo e sem ambiguidades.
- Desenvolver um modelo rico em conhecimento: objetos têm dados e comportamentos associados. O modelo não deve ser apenas uma estrutura de dados (modelo anêmico), ele deve capturar o conhecimento do domínio para resolver os problemas do domínio.
- Destilar o modelo: o modelo deve ser refinado. Assim como conceitos importantes devem ser adicionados, conceitos que não tem relevância devem ser removidos. A cada iteração o modelo ficará mais rico e terá mais valor.
- Brainstorming e experimentação: a interação direta entre os desenvolvedores e domain experts, através de brainstormings e diagramas feitos na hora, transformam as discussões em laboratórios do modelo, no qual diversas variações de experimentos podem ser exercitadas e o resultado pode ser usado se mostrar valor eu descartado caso contrário.
EVANS (2004)
O modelo deve ser rico! 💰

- O modelo deve ser rico em conhecimento.️️️ ✔️
- Um modelo rico é composto de código expressivo, de regras de negócio e processos bem definidos. ✔️
- Ele expressa o conhecimento nele contido e resolve problemas do domínio.✔️
- É o contrário de um modelo anêmico onde as classes são apenas esquemas de dados sem comportamento. 😷
Conclusão
Da próxima vez que você for inferir se um projeto está usando Domain-Driven Design, antes de olhar para a Solution Explorer da IDE em busca do padrão arquitetural e dos building blocks, veja primeiro se a equipe está usando um método ágil e fazendo knowledge crunching.
Eu já vi projetos autodenominados “com DDD”, onde o código até implementava os building blocks deste, mas cujo modelo estava bem longe de refletir o domínio.
Referências
Evans, Eric. Domain-Driven Design: Tackling Complexity in the Heart of Software. 2004.

