Strategic Design com Domain-Driven Design

Maycon Teixeira
11 min readJun 6, 2022

--

Olá, eu espero que você esteja bem! Neste artigo eu falarei um pouco sobre Design Estratégico, um conjunto de conceitos propostos pelo Domain-Driven Design essenciais para nos ajudar a amadurecer o entendimento sobre o negócio de uma organização nos dando recursos para realizarmos análises estratégicas de alto nível e conhecer as etapas de design dentro das restrições de um determinado projeto.

Domain-Driven Design

DDD é um assunto extremamente falado no mundo de desenvolvimento de software, porém devido a sua complexidade e a confusão entre a teoria e a prática acerca do assunto faz ser muito comum vermos uma confusão clara entre DDD e conceitos rasos de design de código.

Com o intuito de reduzir um pouco esse ruído no entendimento vou trazer duas definições de quem é referência no assunto e tentar, mesmo que bem rapidamente, passar por essas definições.

Nas palavras de Vaughn Vernon, autor de livros como Implementing Domain-Driven Design e Domain-Driven Design Distilled, DDD é:

Um conjunto de ferramentas que o auxiliam no projeto e implementação de software oferecendo um alto valor, tanto estrategicamente quanto taticamente.

Aqui vemos uma menção de dois pilares do DDD, o valor estratégico e o valor tático. Estes valores tem como base padrões nos quais podemos nos basear para construir e modelar nosso domínio de negócio focando em deixar o mais explícito possível o que de fato importa: o próprio negócio.

Já nas palavras de Eric Evans, quem cunhou o termo no livro Domain-Driven Design: Tackling Complexity in the Heart of Software, DDD é sobre:

Representar, por meio de um conjunto de conceitos e relações entre os modelos, um entendimento compartilhado do negócio afim de incorporá-lo profundamente na implementação onde eles podem fornecer alavancagem em todos os seguimentos do projeto.

Nessa tradução livre retirada de um trecho do livro citado acima, Evans fala sobre modelos de negócios incorporados à implementação. O que podemos entender disso é basicamente: Nossos modelos devem ser construídos focados no domínio para que nosso entendimento técnico e de negócio estejam sempre falando a mesma linguagem.

É importante entender que grande parte dos livros sobre DDD, são livros com conteúdos bastante densos e subjetivos. Há diversas interpretações a respeito deste tema e é bastante difícil querer definir quais são as mais ou menos corretas, principalmente porque cada necessidade vai eleger uma interpretação diferente como a que mais se encaixa para seu respectivo cenário. Portanto é importante diversificar o quanto possível as referências de estudos para não ficarmos presos à interpretações específicas.

Design Estratégico

Agora que sabemos do que se trata o Domain-Driven Design, ou pelo menos agora que repassamos o conceito superficialmente, vamos iniciar nosso entendimento sobre o que é o Design Estratégico do Domain-Driven Design e como ele pode nos apoiar durante toda a descoberta de negócio.

O Design Estratégico é um conjunto de ferramentas que nos apoia a entender o que é estrategicamente importante para o negócio da organização e nos orienta a tomar decisões importantes.

Para ampliarmos nossa visão do conceito, precisamos aprender, mesmo que de forma superficial, outros dois conceitos propostos que estão diretamente relacionado ao Design Estratégico: Espaço do Problema e Espaço da Solução.

Espaço do Problema

Espaço do Problema é onde nós devemos analisar estrategicamente e em alto nível todo o escopo do projeto conhecendo suas limitações, os objetivos e os riscos envolvidos, concebendo desta forma as fronteiras de negócio e o mapeamento entre estes contextos.

Espaço da Solução

Espaço da Solução é onde nós implementamos as soluções para os problemas identificados. Neste caminho nós já temos identificados quais são os contextos de negócios e principalmente qual é o Core Domain. Já sabemos como todos os contextos vão interagir entre si e já podemos transpor isso para o código.

Colocando em vias práticas, o Espaço do Problema se refere à “que tipos de problemas do negócio nós estamos tentando resolver?” enquanto o Espaço da Solução se refere à “como podemos resolver os problemas apresentados pelo Espaço do Problema?”. Logo, perceba que eles são antônimos e representam uma ordem cronológica de realizações, já que não podemos saber como resolver um problema que ainda não conhecemos.

Em completude ao Design Estratégico, temos mais um conceito importante para deixarmos introduzido, o Design Tático.

Design Tático é um conjunto de recursos, assim como o Design Estratégico, porém focado nos detalhes do modelo de domínio que fora estruturado e fundamentado durante todo o processo de Design Estratégico. Alguns recursos conhecidos do Design Tático são os Agregados e os Eventos de Domínio.

Design Estratégico e Design Tático são conjuntos de conceitos propostos pelo Domain-Driven Design que podem ter relevância e serem aplicados a qualquer momento ou em um momento específico.

Ilustração dos conceitos do Design Estratégico representados em um gráfico de quadrantes com os conceitos vistos acima.

Ampliando a visão sobre Design Estratégico

Para entender mais sobre o Design Estratégico, vamos conhecer sobre cada um dos conceitos que são abrangidos por ele.

Para introduzir o entendimento, vamos começar ampliando nosso campo de visão.

Toda a representação de negócio no qual um software se baseia é chamado de Domínio. O Domínio contém um conjunto de Contextos Delimitados que possuem uma Linguagem Onipresente, estrita e expressiva. Os Contextos Delimitados possuem este nome, pois suas fronteiras são explícitas e claras. Os Contextos Delimitados dentro do Domínio podem se comunicar entre si utilizando Mapeamentos de Contextos.

Da mesma forma que o Domínio contém um conjunto de Contextos Delimitados ele também possui uma divisão em Subdomínios. Isso é possível, pois como vimos mais acima, os Subdomínios e Contextos Delimitados são conceitos utilizados em momentos diferentes e possuem razões diferentes para existirem.

Em resumo, os Subdomínios no Espaço do Problema são mapeados para os Contextos Delimitados no Espaço da Solução.

Porém, esse mapeamento nem sempre é tão simples quanto dito acima. Um Subdomínio pode ser mapeado para um ou mais Contextos Delimitados, assim como dois Subdomínios podem ser mapeados para apenas um Contexto Delimitado. Este tipo de situação não é a ideal, porém nada impede que aconteça.

Não vamos descer mais na estrutura de conceitos do DDD, porque este nível é o que nos interessa no que diz respeito ao Design Estratégico. Todos os termos em destaque citados acima são conceitos propostos pelo DDD afim de tornar a modelagem de negócio mais objetiva, coesa e consistente.

Linguagem Onipresente

Linguagem Onipresente é sem dúvida nenhuma um conceito chave de DDD e consequentemente do Design Estratégico.

A Linguagem Onipresente é uma linguagem comum entre todos os membros da equipe dentro das fronteiras do Contexto Delimitado do qual essa equipe faz parte e quando qualquer membro da equipe fala nesta linguagem, todos os outros conseguem entender e compreender facilmente de forma precisa e sem ambiguidades.

Para que a linguagem atinja o nível de maturidade desejado, é importante que ela seja estrita, exata, rigorosa e expressiva, esteja sempre presente nos diagramas e nas modelagens de software, respeitando sempre a fronteira do Contexto Delimitado. Ela é criada e estabelecida durante todo o processo de levantamento e compreensão do negócio que envolvem os especialistas de domínio e equipe técnica e deve ser praticada e exercitada durante todo o ciclo de vida do software por todos os membros da equipe.

Contexto Delimitado e Subdomínio

O Contexto Delimitado representa uma fronteira contextual semântica, onde um modelo de domínio é aplicável. Em outras palavras, um Contexto Delimitado é um contexto que abrange um segmento do negócio específico, com um time específico e uma linguagem específica.

Os conceitos de Contexto Delimitado e Subdomínio podem parecer bastante confusos inicialmente, pois ambos são delimitações de fronteiras dentro do Domínio ou Modelo de Domínio que podem se cruzar ou estar em harmonia em uma relação de 1 para 1 entre si.

Os Subdomínios são traçados com o objetivo de fazer com que o Domínio possua mais significado e que os setores da organização fiquem evidentes. Como já vimos anteriormente, o conceito de Subdomínio é utilizado no Espaço do Problema, quando ainda estamos tentando identificar as limitações de negócio e os problemas que precisamos resolver.

Existem três tipos de Subdomínios e veremos todos eles a seguir.

Core Domain

O Core Domain possui o contexto de expertise no qual o negócio da organização funciona. É o contexto que faz o dinheiro circular, é o ponto central que não pode parar de funcionar e que deve ser mantido e melhorado com o absoluto foco. Possui investimentos estratégicos construindo uma Linguagem Onipresente robusta em fronteiras bem traçadas e explícitas.

Suporte

São as delimitações que não fazem parte do Core Domain e não possui disponível para a venda ou por código aberto. Mesmo que se trate de um contexto do qual o Core Domain não consegue existir sem, ele não pode ter o mesmo investimento e pode ter terceirizado.

Genérico

É o tipo de delimitação na qual a solução está disponível com códigos abertos ou disponível para compra, como um serviço, por exemplo. A solução também pode ser terceirizada ou ter seu próprio time, porém é importante que não receba os mesmos investimentos feitos no desenvolvimento do Core Domain ou mesmo no Subdomínio de Suporte.

Voltando a falar sobre o conceito de Contexto Delimitado, apesar de poder ser discutido ainda no Espaço do Problema, é no Espaço da Solução que ele ganha relevância, sendo inserido no Modelo de Domínio.

Em uma modelagem otimizada de domínio nós teremos sempre uma relação de 1 para 1 entre Contexto Delimitado e Subdomínio formando um Contexto Delimitado Limpo. Um Contexto Delimitado Limpo pode ser representado em nosso modelo de forma única, pois possui uma responsabilidade única e objetiva.

Em um cenário onde o Core Domain não pode ser representado por um Contexto Delimitado Limpo, ou seja, onde temos mais de um Subdomínio dentro do Contexto Delimitado que possua o Core Domain, nós podemos explicitar essa divisão entre os dois com os Módulos.

Os Módulos no Domain-Driven Design nada mais são que uma maneira de organizar o código de forma eficiente, como por exemplo utilizando namespaces.

É de suma importância que o Core Domain esteja explicitamente em um Módulo diferente do outro Subdomínio do Contexto Delimitado.

Perceba aqui que está explícito que estamos falando do Espaço da Solução. No cenário acima, nós temos 2 Subdomínios identificados, um sendo o Core Domain e outro um Subdomínio qualquer de suporte ou genérico, porém que foram mapeados para um mesmo Contexto Delimitado. Para isso, usamos os módulos, que é um conceito estratégico de solução para mantermos explícita a diferença entre ambos.

Para aplicarmos o conceito de Core Domain, precisamos inevitavelmente responder a seguinte questão: “O que define o negócio e o que o torna um competidor no mercado?”. Talvez seja uma pergunta óbvia, mas ela estabelece um dos conceitos mais importantes no Domain-Driven Design.

Vaughn Vernon em seu livro Domain-Driven Design Distilled ressalta a importância de saber em detalhes o que torna o negócio um competidor no mercado. Somado à isso, ele também fala sobre a importância da organização não tentar obter excelência em todos os aspectos de negócio que estão em volta do Core Domain, pois muito provavelmente ela falhará. Focar no Core garantirá que o que dá dinheiro para a organização esteja sempre com a equipe mais experiente e capacitada e com a devida atenção.

É natural que no Core Domain fiquem sempre os profissionais mais experientes, tanto os técnicos quanto de negócios e que o próprio negócio seja discutido com bastante frequência.

É comum ficarmos confusos quando pensamos no Core Domain como um Subdomínio, mas a verdade é que a expressão Core Subdomain não soaria tão relevante quanto de fato é e esse é o motivo pelo qual você irá encontrar na literatura referências ao Core Domain como um conceito à nível de um Contexto Delimitado e isso é normal.

É importante dizer que sempre que discutimos sobre um projeto em que o DDD está sendo adotado nós estamos falando majoritariamente sobre o Core Domain.

Mapeamento de Contexto

O Mapeamento de Contexto representa uma relação entre dois Contextos Delimitados.

Revisando de forma rápida, nós vimos anteriormente que cada Contexto Delimitado possui uma Linguagem Onipresente própria. Partindo deste princípio, é quase inevitável não pensar na questão: como poderia dois contextos delimitados se comunicarem entre si se, por exemplo, para cada um deles, o significado de um mesmo artefato organizacional possui nomes e significados diferentes?

Este é o objetivo dos Mapeamentos de Contextos, fazer com que duas equipes trabalhem juntas, mesmo estando em contextos diferentes e falando linguagens diferentes no que se refere ao negócio. Os Mapeamentos de Contextos podem ser considerados uma espécie de tradutores.

Assim como qualquer relacionamento entre duas estruturas não existe uma forma padrão de fazê-la. Existem tipos de relacionamentos diferentes que se encaixam em culturas, modos de trabalho e necessidades diferentes.

Vamos entender os principais tipos de relacionamento que podem ser representados pelo Mapeamento de Contexto.

A seguir veremos o termo Upstream e Downstream que são basicamente quem fornece e quem recebe, respectivamente. Quando estes termos não estiverem presentes, entende-se que o relacionamento é bilateral, ou seja, ambos os lados se beneficiam do relacionamento.

Parceria

Parceria é um relacionamento entre duas equipes que criam objetivos relacionados e dependentes, dessa forma ambas as equipes vão progredir ou falhar juntas.

Por conta desse alinhamento bem próximo, as equipes vão precisar ter uma agenda bem frequente de encontros e vão precisar trabalhar juntas, principalmente em tudo o que for referente à integração.

Este tipo de Mapeamento de Contexto se torna ao passar do tempo cada vez desafiador de se manter devido ao grande acoplamento entre as equipes e o indicado é que ao longo do tempo esse relacionamento seja repensado para outro tipo de Mapeamento de Contexto.

Kernel (ou Núcleo) Compartilhado

Kernel Compartilhado é um relacionamento entre duas ou mais equipes em que ambas compartilham de um mesmo modelo. As equipes definem juntas quais modelos devem ser compartilhados para que a integração faça sentido, construindo assim um modelo único de integração.

É possível que apenas uma das equipes trabalhem para manter e cuidar do build e testes do modelo compartilhado, mas isso não é uma regra.

A comunicação neste tipo de Mapeamento de Contexto deve ser tão frequente quanto no formato de Parceria para que as equipes estejam sempre em acordo sobre o que deve estar em compartilhamento.

Cliente-Fornecedor

Cliente-Fornecedor é um relacionamento entre duas equipes em que o Fornecedor (Upstream) domina a relação provendo apenas quando e como ele deseja o que o Cliente (Downstream) precisa.

Conformista

Conformista é um relacionamento em que a equipe Dowstream não consegue manter os esforços para se integrar ao Upstream e o Upstream, por sua vez, não possui motivações para suportar as necessidades do Downstream.

Camada de Anti-Corrupção

Camada de Anti-Corrupção é um relacionamento defensivo por parte do contexto de Downstream em que ela cria uma camada de tradução própria entre ambas as linguagens, isolando completamente ambos os modelos. Desta forma o contexto de Upstream precisa apenas manter o contrato definido com o contexto de Downstream ou sempre comunicar quando alguma mudança for ocorrer.

Criar uma Camada de Anti-Corrupção para integrações é uma abordagem extremamente recomendada, pois podemos construir modelos que se encaixam perfeitamente ao nosso contexto.

Serviço de Hospedagem Aberto (Open Host Service)

Open Host Service não é um relacionamento propriamente dito, mas sim um protocolo definido por um Contexto Delimitado em que é permitido o acesso ao seu próprio modelo.

Este serviço pode ser disponibilizado por uma API, por exemplo com contratos bem definidos e bem documentados.

Este tipo de integração sugere schemas prédefinidos como XML, JSON, Protobuf ou Avro, por exemplo.

O contexto de Downstream por sua vez acessa por meio de uma rota específica fornecendo os parâmetros específicos e pode aplicar uma Camada de Anti-Corrupção para a tradução segura dos dados.

Não integração…

A não integração também é um caminho. Quando ambos os contextos não enxergam nenhuma vantagem para que a integração seja justificada cada equipe constrói seu próprio caminho para a solução.

Conclusão

Neste artigo falamos sobre o Design Estratégico, o principal conjunto de conceitos e ferramentas do Domain-Driven Design. Nós falamos também sobre cada um deles e como eles podem nos ajudar na modelagem do nosso domínio.

Muito obrigado por ter lido até o final, todos os comentários, discussões, sugestões e críticas são muito bem vindos. Até mais!

Versão 1

--

--

Maycon Teixeira

I’m agnostic about technology. I like to learn about any interesting thing in the tech world, even if it makes me start again from scratch.