Modelando o Context map do zero

Domain Driven Design: Modelando context map do zero (em 7 passos simples)

O assunto Domain Driven Design é algo profundo que precisa ser constantemente trabalhado nas empresas com softwares de grande porte. Por conta disso temos um pequeno apanhado de artigos sobre o tema. O artigo Modelando um Context map do zero exemplifica um modelo real e os passos para que ele seja construídos. Já os outros artigos criados podem ajudar no entendimento, mas não são obrigatórios.

De modo geral é importante entender que o Domain Driven Design tem aspectos estratégicos, ou seja, ligados a definições de alto nível que norteiam a aplicação; e aspectos táticos, que descrevem formas de se estruturar aplicações para alcançar os objetivos observados na estratégia. Esse artigo tem um viés estratégico mas não teórico, portando o resultado desse artigo será geração de código, conjunto de procedimentos e diagramas.

Solução de referência

Para tal uma aplicação de exemplo está sendo construída: trata-se de uma casa de câmbio (ou Exchange) de criptomoedas chamada AnselmeX. No momento que estou escrevendo esse artigo ela não está pronta e, portanto, não terá nenhum meio de acessa-la. Além disso o código fonte no github ainda está bastante incipiente. Caso esteja lendo esse artigo no futuro é possível que tais produtos estejam mais avançados.

Por outro lado o objetivo é entender o domínio e seus sub-domínios e tornar compreensível como o processo pode ser feito. E após isso, mapear os contextos (bounded contexts) e gerar o mapa de contexto (context map) da aplicação. Note que não há nenhum especialista do domínio envolvido, desse modo há um prejuízo na linguagem utilizada para definir a solução, mas vale como inspiração.

Elementos importantes para a solução

O endereço da solução é (não há nenhuma garantia de que a solução esteja disponível agora) https://www.anselme.com.br/anselmex. E o repositório é (ele pode estar incompleto e não trazendo a solução em si ou detalhes relevantes no momento) https://github.com/Anselming/ddd-anselmex.

Artigos relacionados

Modelagem de domínio

A modelagem de domínio tem como objetivo destacar os elementos estratégicos do DDD em domínios e subdomínios. Mas além disso o modelo evidencia os eventos de domínio associados. A utilização da técnica de Event Storming se fez presente de modo a facilitar todo esse processo.

Além disso utiliza-se o VSCode para todo o trabalho gerando diagramas .dio (draw.io) e um mapa de contexto em CML (Context Mapper DSL). Essa mistura gera alguns diagramas elegantes e um código que torna mais tangível a interpretação. Nesse artigo (Modelando o Context map do zero) não vamos trabalhar com o detalhamento dos agregados (sem detalhes mas está presente no artefato final), entidades, value objects, e outros elementos táticos do domain driven design.

Corretora Anselmex

A Corretora hipotética Anselmex oferece meios para que qualquer um possa ser usuário dela. Para tal é necessário se cadastrar mas a plataforma de reserva a verificar com algum órgão de crédito (SPC, SERASA, etc.) se o usuário é bom pagador. Assim a plataforma suporta aportes ou retiradas em diversas moedas fiat (real, euro, libra, dolar, etc.) e de moedas cripto (bitcoin, cardano, dogecoin, litecoin, etc.). Além disso é possível fazer ordens de compra/venda de moedas. Além disso caso alguém se interesse pelas condições ele pode fechar uma transação, trocando moedas de um para outro: ao fazer isso a plataforma é agraciada por um fee (taxa).

Para que essa solução funcione também é necessário pensar em algumas características internas como: para moedas fiat é necessário ter contas bancárias configuradas para uso através da plataforma. Para moedas cripto é necessário ter carteiras protegidas para lidar com os saques e depósitos realizados.

Por fim a solução também suporta trabalhar com NFTs lidando com o registro de um NFT, a listagem para venda e as operações de compra e venda associadas.

Essa solução é falsa e certamente há um grande conjunto de situações não exploradas no exemplo. Mas entenda que é uma simulação e não háo compromisso em ser preciso, mas sim de demonstrar como pode ser o processo de geração do mapa de contexto.

Mapeando: passo a passo

Fase 1 – Event Storming

Nessa fase há um brainstorming de eventos que ocorrem no AnselmeX. Os eventos são expressões no particípio que descrevem algo bem específico. Veja a seguir alguns exemplos:

  • Usuário logado
  • Usuário deslogado
  • Usuário bloqueado
  • NFT Criada
  • NTF vendida
  • etc.

Seguindo na técnica, deve-se descobrir qual ação é feita para que o evento ocorra. De maneira geral é bastante intuitivo:

  • Para ‘Usuário logado’ é necessário executar o ‘Login’
  • Para ‘NTF comprada’ é necessário executar o ‘Comprar NFT’

E por fim é necessário definir quem é que faz a ação em si. Veja mais ou menos como ficou:

Exemplo de Event Storming para DDD (Domain Driven Design) com caso prático para uma corretora hipotética de criptomoedas.

Fase 2 – Cronologia dos eventos

Após todos os eventos serem definidos (ou o máximo possível) eles precisam ser colocados em ordem de tempo. Note que alguns ocorrem ao mesmo tempo e outros não. Alguns são feitos por determinados usuários e outros por serviços autônomos. Para facilitar a cronologia da AnsemeX foi feita em linhas, uma para cada ator relacionado.

Exemplo de Event Storming para DDD (Domain Driven Design) com caso prático para uma corretora hipotética de criptomoedas. Exibição de uma cronologia de eventos.

No modelo que apliquei preferir eliminar do diagrama outros elementos do event storming, mas cada caso é um caso. Entenda seu cenário e adapte como julgar necessário.

Fase 3 – Separando em grupos

Após ver toda a cronologia notei que alguns conjuntos de eventos têm relação entre si. Já outros são bem distantes ou nem podem se relacionar. Para fazer isso adicionamos um travessão amarelo ao fim de um evento que delimita o que arbitrei como um grupo.

Exemplo de Event Storming para DDD (Domain Driven Design) com caso prático para uma corretora hipotética de criptomoedas. Separação de contextos.

Além disso, colocamos essa linha pontilhada agrupando um conjunto de eventos num só bloco. No exemplo acima note que todos os eventos são relacionados a NFT: alguns de manipulação do NFT (criação, listagem para compra/venda) já outros são referentes às transações de compra e venda em si.

Note que esse processo é bastante arbitrário. No mundo real esse processo deve ser feito junto aos domain experts do jeito mais gostoso possível, dependendo da habilidade do mediador. Note que esse não é momento de focar em conflitos do tipo ‘isso é problema do fulano e não meu’: evite os conflitos antes de ter as cartas na mesa (Modelando o Context map do zero).

Fase 4 – Identificação dos domínios

Agora que já há agrupamentos definidos, linhas de tempos de eventos e os atores relacionados, é possível extrair uma visão macro desses elementos. Essa visão macro esclarece quais são os subdomínios da aplicação e como eles se posicionam: genéricos (podem ser tercerizados), suporte (o core precisa para funcionar), core (a razão de ser do negócio).

Os domínios encontrados foram:

  • Account (Support)
  • Login (Support)
  • Wallet (Core)
  • Withdrawal (Core)
  • NTF (Core)
  • Transaction (Core)
  • CreditBody (Generic)

Fase 5 – Identificação dos bounded contexts

Os contextos já foram encontrados na fase 3, mas não fazem parte do context map ainda. Os grupos menores normalmente estão relacionados a um especíalista de domínio particular, mas varia de caso a caso. O mapa do domínios (da fase 4) só tem relação com o chamado espaço de problema. Mas ele pode ser enriquecido colocando os contextos em seus domínios relacionados. Veja mais ou menos como está ficando:

Mapa de domínios hipotético para um corretora de criptomoedas.

Fase 6 – Relacionando contextos

Está ficando muito legal mas ainda falta observar quais contextos falam com quais outros. a cronologia deve dar essa resposta, mas se não der talvez estejam faltando eventos no mapeamento. Veja que ao fazer esse trabalho eu notei que tive que corrigir vários pontos a medida que as fases vão passando: Isso faz parte e é muito positivo.

Mapa de domínios hipotético para um corretora de criptomoedas. Há relação entre os bounded contexts (contextos).

O objetivo dessa fase é só correlacionar e não ir além disso. Só de entender as relações já dá para ter uma boa dinâmica de como pode ser esse software.

Fase 7 – Criando o arquivo CML

Para finalizar vamos partir para a criação do arquivo CML que descreve o mapa de contexto. Note que esse trabalho fará apenas a modelagem estratégica e, portanto, elementos como agredados (aparece sem detalhes), value objects, etc. não farão parte do artigo (Modelando o Context map do zero), mas são opções possíveis caso entenda ser necessário em seu caso.

O arquivo CML se divide em 3 grandes partes:

  • O domínio e seus subdomínios
  • Os bounded contexts
  • O context map e suas relações

O domínio e seus subdomínios

Simplesmente adicione cada sub-dominio mapeado, sua tipagem e uma pequena descrição. Há outros parâmetros possíveis mas esses foram suficientes.

Domain CryptocurrencyExchangeDomain {

	// Core
	Subdomain WalletsDomain {
		type = CORE_DOMAIN
		domainVisionStatement = "Sub-domínio responsável por criar carteiras para o usuário utilizar. Também é responsável pelo controle das contas utilizadas pela corretora (fiat ou crypto). Também lida com a autorização de uso de carteiras ou de cancelamento delas."
	}
	Subdomain WithdrawalsDomain {
		type = CORE_DOMAIN
		domainVisionStatement = "Sub-domínio responsável por fazer saques ou remessas para a conta corretora, seja em moedas fiat ou crypto."
	}
	Subdomain NftDomain {
		type = CORE_DOMAIN
		domainVisionStatement = "Sub-domínio responsável por criar, listar, remover, comprar, vender, etc. NFTs dentro da plataforma."
	}
	Subdomain TransactionsDomain {
		type = CORE_DOMAIN
		domainVisionStatement = "Sub-domínio responsável por fazer ordens de compra e venda, efetivamente comprar e vender moedas (fiat x crypto, crypto x crypto)"
	}

	// Support
	Subdomain AccountsDomain {
		type = SUPPORTING_DOMAIN
		domainVisionStatement = "Sub-domínio responsável por receber solicitações, criar contas, validar (podendo utilizar terceiros), fazer kyc, validação de docs, e afins."
	}

	Subdomain LoginsDomain {
		type = SUPPORTING_DOMAIN
		domainVisionStatement = "Sub-domínio responsável por lidar com a conta de usuário, permissões e direitos do usuário."
	}


	// Generic
	Subdomain CreditBodyDomain {
		type = GENERIC_SUBDOMAIN
		domainVisionStatement = "Responsável por lidar com entidades externas que auxiliem em fazer verificações de crédito (como SPC, SERASA)."
	}

}

Os bounded contexts

Para não ficar muito grande não coloquei aqui todo o código fonte dos bounded contexts, mas entre no repositório https://github.com/Anselming/ddd-anselmex para encontrar todo o código.

Note que a configuração é simples identificando tipo, uma descrição, a linguagem, responsábilidades e a partir daí aparecem elementos táticos. Aqui só aparece o agregado, mas é possível detalhar mais: isso depende exclusivamente da sua necessidade e possibilidade.

BoundedContext UserWallet implements WalletsDomain
{
	type = FEATURE
	domainVisionStatement = "Esse contexto lida com todas as carteiras que o usuário possui no sistema"
	implementationTechnology = "C#"
	responsibilities = ""
	
	Aggregate Wallet
}

O context map e suas relações

Por fim, essa é a fase mais complexa. Por um lado se identifica o tipo do mapa de contexto, que bounded contexts se relacionam: essa parte é bem fácil. Já na segunda parte há a relação entre os contextos. Esse trabalho já foi feito na fase 6, porém sem um nível de detalhe que se faz necessário aqui.

Para entender melhor, note que os contextos são ligados por setas. Elas indicam o sentido da relação. Já, por fora há um couchete com letras que identificam o tipo de relação:

  • U = upstream
  • D = downstream
  • P = partnership
  • S = supplier
  • C = consumer
  • ACL = Anti-corruption layer
  • CF = conformist
  • OHS = Open-host service

Para mais detalhes sobre essa relações consulte o artigo Criando Context maps DDD com o VS Code.

ContextMap Anselmex {

	type = SYSTEM_LANDSCAPE
	state = TO_BE

	contains UserWallet , InternalWallet 
	contains Withdrawals 
	contains NftCreation , NftTransaction 
	contains Transactions 
	contains AccountsRequests , AccountsCancellations, AccountsCreation
	contains Logins
	contains CreditBody
	
	AccountsRequests [P]<->[P]  AccountsCreation
	AccountsCreation [U,S]->[D,C]  AccountsCancellations
	AccountsCreation [P]<->[P] UserWallet
	AccountsCreation [U]->[D,ACL] CreditBody
	AccountsCreation [U,S]->[D,C] Withdrawals

	Logins  [D,C]<-[U,S]  AccountsCreation
	Logins  [D,CF]<-[U]  AccountsCancellations
	
	Withdrawals [D,C]<-[U,S] InternalWallet
	Withdrawals [D,C]<-[U,S]  UserWallet
	Withdrawals [D,C]<-[U,S]  NftTransaction
	Withdrawals [D,C]<-[U,S]  NftCreation
	Withdrawals [D,C]<-[U,S]  Transactions

	UserWallet [U,OHS]->[D] Transactions
	UserWallet [U,OHS]->[D]  NftTransaction
	UserWallet [P]<->[P]  InternalWallet	

}

O mapa de contexto

Depois de todo esse trabalho temos a seguinte obra prima: o context map do AnselmeX. Com esse diagrama em mãos é possível começar a pensar em algumas característica de arquitetura, composição direta de squads, squads de plataforma, necessidades de api gateways, message brokers, etc. Mas não se apresse: ainda há muito o que fazer com os especialistas de domínio para esclarecer os seus contextos, extrair mais informações relevantes, regras e restrições e, fique tranquilo, esse diagrama ainda pode mudar. Link da imagem: Context Map.

Conclusão de Modelando o Context map do zero

Note que fazer esse diagrama dá certo trabalho mas não é algo propriamente difícil. Acho que o ponto mais importante é entender que a relação com o especialista do domínio é completamente fundamental para que o context map reflita a realidade o negócio. Além disso, é importante ter um moderador que entenda bem o que está fazendo. Os domains experts devem ter certa familiaridade com ferramentas como essa para aumentar a chance de sucesso. E é importante ter em mente que a cultura da empresa guia como tais ferramentas fluem.

Esse diagrama foi feito sem domain experts, portanto ele é interessante para estudo, mas dificilmente estará certo. De todo modo, um projeto de verdade precisa prosseguir, fazendo novas análises e continuamente ir atualizando e adaptando, seja do ponto de vista da estratégia, seja da tática.


Thiago Anselme
Thiago Anselme - Gerente de TI - Arquiteto de Soluções

Ele atua/atuou como Dev Full Stack C# .NET / Angular / Kubernetes e afins. Ele possui certificações Microsoft MCTS (6x), MCPD em Web, ITIL v3 e CKAD (Kubernetes) . Thiago é apaixonado por tecnologia, entusiasta de TI desde a infância bem como amante de aprendizado contínuo.

2 comentários em “Modelando o Context map do zero

  1. Parabéns pelo artigo !!!
    Leitura fácil entendimento, bem didático, bem estruturado. Muito bom mesmo. Eu estou sempre lendo esse tipo de conteúdo, já li o livro 3 vezes e fora outros conteúdos(blog, podcast, etc …). Sempre tem um detalhe que acaba passando.

    +1 vez Parabéns !!!!!

Deixe um comentário