Domain-Driven Design Estratégico: Extraindo Sub-domínios com EventStorming
Tags: ddd, domaindrivendesign, business, softwaredevelopment
Published: 2024-03-05 10:18:11

Os últimos artigos publicados, foram determinantes para a formação da base necessária sobre a compreensão sobre o que é, o como devemos lidar e qual importância tem a parte **Estratégica** do Domain-Driven Design.

Foram apresentadas algumas técnicas auxiliares que ajudarão a aumentar a compreensão sobre domínios de negócio, e para além disso também melhorar a identificação e compreensão dos requisitos desejados para um produto de software.

Agora, já estamos quase prontos para seguir adiante nessa jornada, aplicando as práticas estratégicas do **Domain-Driven Design**, vou te fornecer mais ferramentas que te capacitarão a desdobrar o domínio de um sistema proposto: **FoodDelivery,** identificando, neste artigo, os **sub-domínios**.

---

⚠️ *Caso você caiu nesse artigo e ainda não entende a definição de sub-domínio, te convido a dar uma pausa nessa leitura e ler o [post anterior](https://dev.to/emergingcode/domain-driven-design-de-forma-estrategica-destilando-o-dominio-22ej).*

---
Vamos refinar um pouco mais alguns conceitos básicos e consolidá-los no nosso conhecimento.

O tema sub-domínios leva muitas pessoas ao entendimento de que cada unidade de negócio, dentro de uma empresa, pode ser considerada como um sub-domínio, per-si. Isso é um equívoco comum de acontecer.

Vamos usar o exemplo de um sistema PetClinic. Dentro desse sistema, vão existir várias áreas de negócio, com suas respectivas regras, modelos, pessoas responsáveis, e interações e comunicações entre as outras partes do sistema. Tais áreas podem ser: **Gestão de pacientes, agendamento de consultas, registros veterinários de um pet**. Olhando para esse sistema, fatalmente o entendimento mais comum seria: *Vamos assumir que cada área dessas vai ser nosso sub-domínio* 🤔.

💭 _Nem sempre tudo aquilo que se observa com frequência é a verdade absoluta das coisas._

> Tudo que se vê não é! - **Lulu Santos.**

Dando continuidade ao exemplo acima, peço que você remova o véu de tudo o que você já viu de projetos de código, supostamente, aplicando técnicas do DDD, e me acompanha cuidadosamente nessa explicação sobre *Sub-domínios e Domínios de negócio*.

Analisando o fato já externalizado acima, é possível perceber que teríamos, supostamente, 3 sub-domínios distintos: **Gestão de pacientes, agendamento de consultas, registros clínicos de um pet**. 

Vamos levantar algumas provocações sobre as informações que já temos em mãos: Poderia a gestão de pacientes e agendamento de pacientes, pertencerem ao mesmo departamento ou unidade de negócio? **Claro que sim**! Outra agora mais intrigante: **Parte** da gestão de pacientes, poderia pertencer a mais de um departamento? Sim ✅. Essa é a razão pela qual, ao modelar o domínio principal de uma empresa, não se deve ficar apegado aos departamentos que a empresa possui, apesar deles te ajudarem a ter uma visão geral de como a empresa está dividida.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2m1v5xfvoeh6s0tg0rgk.png)

Vamos imaginar uma plataforma online de streams de filmes, similar a Netflix. Nessa plataforma haverão separações de áreas (*sub-domínios*) distintas por funcionalidade, onde cada uma delas vai ter suas próprias: *Regras, fluxos, linguagem e implementação*.

- Catalogo de filmes **sub-domínio**: Esse sub-domínio tem a responsabilidade de fazer a gestão sobre o catalogo de filmes e séries:
    - Registrar um filme/série
    - Atualizar informações de um filme
    - Categorizar o contéudo (*filmes de suspense, comédia, ação*)
- Player **sub-domínio**: Esse sub-domínio vai gerir COMO é consumido o conteúdo do catálogo e vai gerir a execução desse conteúdo para o usuário:
    - Play (tocar) o conteúdo
    - Pause (pausar)  o conteúdo
    - Tracking time (gestor de tempo) do tempo assistido.
- Gestão da conta do usuário **sub-domínio**: Nesse sub-domínio será onde acontecerá a gestão de conta de cada usuário da platafroma
    - Payment method (forma de pagamento)
    - Quality of Service (Qualidade do serviço: HD, 4K)
    - Address and Contacts (gestão de contatos e endereço)

Ao definir os sub-domínios em um sistema, abre-se espaço para que as pessoas responsáveis pela construção do sistema, tenham uma visão sobre cada uma dessas áreas, e assim possam manter o foco em suas regras e complexidades específicas de cada uma dessas delimitações de unidades. Essa abordagem de descoberta e extração de áreas específicas, permite melhorar a clareza na comunicação entre os times e permite entender até onde cada um pode ir, para além de visualizar os impactos que cada alteração pode implicar uns aos outros.

Existe uma compreensão bastante importante para você ter em mente: _nem tudo é da forma como se vê_. É preciso explorar um pouco mais as necessidades do contexto e perceber a responsabilidade que ele tem dentro da empresa, pois vão existir momentos em que o que hoje você vê como sendo um sub-domínio, pode se tornar um domínio de negócio, contendo outros sub-domínios. A modelagem abaixo ilustra bem essa visão:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7jmxjw52w8ipkgsgqht5.png)

🔎 Observando a modelagem da esquerda, é possível perceber que para a plataforma de ***FoodDelivery***, o negócio não demanda a necessidade de o sub-domínio ***Order*** se tornar um domínio de negócio. Já no diagrama da direita, o planejamento da empresa entende que ***Order*** terá a responsabilidade de gerir todo o ciclo de realização (***fullfilment***) de um pedido (***order***), transformando a área **Order** em domínio core, e que nesse caso está contendo outros 3 sub-domínios.

---

Agora eu acredito que tenha ficado claro para você, o que é um Domínio e o que representa um sub-domínio dentro da modelagem estratégica do DDD. 

❗*Caso tenha ficado alguma dúvida, deixe suas dúvidas nos comentários.*

Mas como eu posso aplicar essas técnicas para descobrir e extrair esses sub-domínios no meu projeto?

Para nos ajudar durante a jornada de exploração e identificação de sub-domínios, existem algumas técnicas que podem ser utilizadas, abaixo eu cito 2:

- Event Storming
- Domain Storytelling

Em projetos que participo, particularmente utilizo o ***Event Storming***, mas o Domain Storytelling se mostra uma excelente técnica para explorar e dar visibilidade aos sub-domínios de um sistema.

Agora vou começar as explorar os diversos comportamentos do sistema, usando **Event Storming**. Existe muito conteúdo sobre esse tema. [Compartilho esse link](https://github.com/mariuszgil/awesome-eventstorming) contendo muitas fontes de estudos sobre o tema.

---

Basicamente, o EventStorming te permite identificar alguns níveis de abstração:

- Visão geral (Big Picture)
- Modelagem de processos (Process modeling/Business Flows)
- Contextos delimitados (Bounded Contexts)
- Personas & Entidades
- Políticas (Policies/Rules)


Cada uma desses pontos identidicados, vão colocar luz sobre aspectos da abstração em si, trazendo idéias e entendimentos valiosos, os quais nos permitirão concretizar a modelagem de um sistema.

### Iniciando a jornada de descoberta

Antes de iniciar o processo de descobertas, vamos entender rapidamente como **EventStorming** define os tipos de cartões, o que cada cor representa para um ticket e como eles facilitam a identificação sobre as responsabilidades, durante todo o workshop. Na imagem abaixo você tem uma legenda:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aex6hgjpbunrog9b5upi.png)



Cada cartão tem a sua responsabilidade e definição dentro do método **EventStorming**. Abaixo estão descritas as definições de cada um:

#### Evento (Event)

Eventos são reações à ações que aconteceram no passado. Usamos os verbos escritos no passado, indicando para o receptor do efeito dessa ação, que ela foi executada. Para modelar um processo de negócios, simplesmente organizamos os eventos da esquerda para a direita em uma sequência temporal.

#### Comando (Command)

Um comando pode ser entendido como uma decisão, ação ou intenção de algo sobre alguma coisa. É a manifestação de interação com o sistema em questão. Comandos são críticos, pois eles representam a intenção de interação de um usuário ou de um outro sistema sobre algum processo. Pro exemplo, quando um usuário expressa a vontade de adicionar um pedido em um e-commerce, é esperado que essa ação seja escrita com o comando: **RegistrarPedido**.

#### Ator/Persona (User)

É o agente responsável por interagir com alguma ação dentro de um determinado fluxo de negócio, e também responsável por uma dada decisão. Por meio desse tipo de cartão que se torna possível identificar pessoas que vão interagir com o sistema ou parte de um fluxo.

#### Modelos de Leitura (Read Model)

Nos permite consultar dados dentro do sistema. Consultamos porque queremos saber algo. Temos perguntas que o sistema pode nos responder, nos permitindo definir alguns limites dentro de uma consulta e retornando os itens que estão dentro dos limites que definimos. O uso dos dados retornados por um modelo de leitura, pode nos ajudar em um processo de tomada de decisão.

#### Hotspot

Em workshops dessa natureza, é absolutamente natural que alguns conflitos de interesses apareçam durante o mapeamento dos fluxos. *Não entenda isso como algo negativo, pois é um evento positivo dentro desse processo*. Um conflito pode ser por uma informação incompleta, um entendimento mal explicado, ou seja, pode ser qualquer coisa que leve pessoas a não entrarem em concordância. Para gerir esse tipo de conflito, usamos o cartão do tipo **Hotspot**, deixando registrado esses pontos de discordância, destacando que há questões que precisam ser resolvidas em um determinado momento durante o desenvolvimento do projeto de software.

#### Política (Policy)

Uma política define regras que reagem aos eventos ou comandos que são emitidos em fluxos de negócio. Você pode pensar em uma política assim "*Sempre que X acontecer, precisamos fazer Y*”, eventualmente terminando dentro do fluxo entre um Evento de Domínio e/ou um Comando/ação. É possível utilizar outra expressão, como: ***Imediatamente à isso.*** Pense no cenário onde um usuário acabou de resgistrar em uma plataforma. Então ***Sempre que o usuário se registrar*** ou ***Imediatamente ao registro do usuário***, o sistema deve enviar um email de boas vindas.

---

🎉 Agora é hora de começarmos a mergulhar em torno do processo de descoberta e mapeamento do domínio do **FoodDelivery.** Durante o processo inicial de identificação dos eventos que podem, eventualmente, acontecer dentro de um sistema, cada participante tem a liberdade de poder identificar o evento que ele/a entender ser importante para adicionar ao quadro (físico ou online). A imagem abaixo, facilita perceber que, neste momento, não existe linha do tempo definida, ainda.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r9ufww8vxck03hggnzsw.png)

Analisando os tickets no quadro acima, você pode observar a disposição potenciais eventos que podem ocorrer dentro de um sistema de **FoodDelivery**. Veja também que foram permitidos apontar vários tipos de eventos:

- Os **relacionados ao negócio**: ***Order Placed***
- E eventos relacionados coisas técnicas. Exemplo: ***Cart requested payment API***

Ainda que sejam cartões de eventos válidos, o nosso foco aqui é sobre os **aspectos relacionados ao negócio**. Por isso, vamos removê-los desse quadro cima.

Após a limpeza dos cartões que não traz relevância para essa análise, o seu quadro deve se parecer como o da imagem abaixo:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jdj0j05lzr2x4o96vxiz.png)

Agora que só temos tickets relacionados ao espaço de negócio, vamos agrupar os tickets com base em alguns critérios:

- Identificar **palavras** semelhantes: Tome cuidado ao analisar o contexto de cada uma delas, afim de classifica-las com base nesse entendimento.
- **Linha do tempo**: Analise os eventos que precisam acontecer antes de acontecer o próximo evento.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/grzu9vx3y5vbh7abbmgt.png)

Esse agrupamento de contextos permite destacar um esboço dos sub-domínios que esse tipo de sistema pode considerar para funcionar. Colocando os cartões em ordem cronológica, temos a seguinte visão:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/71zynocvtuacucu7vfa7.png)

Ao final desse trabalho inicial de descoberta e mapeamento de sub-domínios, esses são os contextos que temos para iniciar os trabalhos. Com a evolução do negócio e com a inclusão de novas funcionalidades, os fluxos tendem a mudar em um dado momento do tempo. Mantenha um snapshot (foto) desse esboço, para que você tenha condições de ir evoluindo esse mapeamento no futuro.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hwu3i63usmpczfx8h746.png)

# Conclusão

Ao final da leitura desse artigo, é fácil perceber que a aplicação das técnicas do Domain-Driven Design não se resumem à apenas programar _Entidades, Agregadores, Serviços de Domínio e entidades correlatas_. Modelar um domínio de negócio, é uma tarefa essencial para a sobrevivência de qualquer sistema **Line-of-Business**.

Entender quais ferramentas e técnicas podem ser aplicadas para rodar essa fase inicial, será o seu divisor de águas entre ter um sistema com uma modelagem de negócio ajustada às necessidades da empresa ou simplesmente reproduzir modelos de repositórios do github.

Não menos importante, também foi possível ter uma visão rápida sobre o que significa cada um dos cartões utilizados no método **EventStorming**. Usando esse conhecimento, avançamos o inicio do brainstorming, levantando todas as possibilidades de potenciais eventos que poderiam ocorrer dentro desse tipo de sistema. Finalizando em um agrupamento contextualizado, começando a dar visibilidade sobre os esboços de sub-domínios.

Agora é seguir para o próximo capítulo dessa série, onde iremos **Refinar**, ainda mais, essa modelagem 👋🏻.

# Referências

- https://www.eventstorming.com/
- https://domainstorytelling.org/
- https://github.com/hofstef/awesome-domain-storytelling