Como desenhar um mapa contextual?— DDD Parte 2

Como desenhar um mapa contextual?— DDD Parte 2


Depois de termos criado nossa linguagem única, iremos para o nosso próximo elemento de análise do domínio: o Mapa Contextual.

Neste artigo passaremos a entender quais são os principais objetivos do nosso mapa, destacando suas diferenças entre outros diagramas, como diagrama de entidades e de classe.

Iremos entender também os tipos de relacionamento entre os elementos do mapa, e como isso afeta e descreve com detalhes as interações entre eles.

Este artigo é o segundo de uma trilogia de artigos sobre Domain Driven Design e seus principais elementos. Os exemplos e cenários apresentados aqui foram elaborados no primeiro artigo da série:
Como construir uma linguagem única? (Parte 1)

O que NÃO É um Mapa Contextual?

Sei que parece contraintuitivo, mas na minha opinião, descrever inicialmente o que não é um Mapa Contextual é muito mais elucidativo do que começar explicando o que ele é.

Isso porque quando nós, como desenvolvedores, vamos começar a desenhar um diagrama, instintivamente imaginamos que devemos mapear as entidades ou classes do nosso sistema, de modo a ilustrar todas as relações entre os elementos do diagrama.

O Mapa Contextual não tem como objetivo ilustrar as relações entre entidades e classes, e por isso não é um diagrama de entidades ou classes.

A citação acima pode parecer óbvia, mas não é tão intuitiva assim quando vamos construir nosso mapa.

Toda vez que você pensar em “repositório”, “serviço” ou “entidade” enquanto idealiza um Mapa Contextual, existe uma grande tendência de que você não esteja idealizando um Mapa Contextual.

A pergunta então é: se não vamos descrever entidades ou classes, então o que vamos usar para construir o mapa?

Lembra dos contextos delimitados?

Um mapa contextual tem como objetivo mapear os contextos delimitados de um domínio, e descrever as relações entre eles.

Lembra do que falamos sobre contextos delimitados no primeiro artigo? Eles definem a semântica dos modelos que temos aplicados dentro deles.

Decidi utilizar a palavra “semântica” ao invés de “significado”, pois :

Semântica é, em um sistema linguístico, o componente do sentido das palavras e da interpretação das sentenças e dos enunciados.

É pelo contexto delimitado que sabemos o significado das entidades da nossa linguagem ubíqua, similar ao contexto que usamos em nossa língua falada e escrita.

Nós não estamos habituados a pensar em contextos quando estamos desenvolvendo. Nosso raciocínio sempre se volta aos elementos dos padrões de código que estamos habituados, por utilizarmos estes elementos com frequência.

Podemos definir de maneira lúdica que um contexto delimitado é composto por:

  • um sentido, semântica ou significado, que serve como condicional agregadora para identificar os modelos que estarão dentro dele.
  • um grupo de modelos (entidades, repositórios, etc) que compartilham uma semântica entre si, total ou parcial.

Na prática, os contextos podem se manifestar de várias formas dentro de um sistema, sendo as mais comuns:

  • como pacotes ou módulos de funcionalidades a serem importados pelo sistema.
  • como um ou mais microserviços definidos em um ambiente de nuvem.

Relembrando nosso cenário

Além da nossa linguagem única, também definimos o nosso cenário de exemplo no artigo passado. Primeiramente, o nosso cenário é:

Uma aplicação móvel de turismo, em que o usuário terá um perfil de viajante e poderá submeter pontos de interesse em um mapa. Esses pontos poderão receber avaliações de outros viajantes.

Além disso, foram abordado alguns tópicos que descrevem melhor o domínio do nosso sistema.

  • Um usuário não pode avaliar o próprio ponto de interesse
  • O usuário precisará fazer um cadastro e criar um perfil na aplicação para poder submeter e avaliar pontos de interesse
  • Esse cadastro poderá ser feito usando suas Redes Sociais (Facebook e Instagram)
  • A avaliação será feita utilizando ranking de estrelas, podendo avaliar de 0 a 5 estrelas, poderá também conter uma ou mais fotos.
  • Outros usuários podem curtir uma avaliação, indicando as mais relevantes. Um usuário não pode curtir uma avaliação feita por ele mesmo.
  • Outros usuários podem denunciar uma avaliação ou ponto de interesse que não tenham sido criados por eles
  • Um usuário não pode avaliar mais de uma vez um ponto de interesse
  • Os pontos de interesse podem ser estabelecimentos, como restaurantes e shoppings, e locais abertos, como parques, trilhas e paisagens naturais.
  • Na submissão de um ponto de interesse, um usuário pode submeter uma ou mais fotos.

Com o nosso cenário em mente, podemos agora construir nosso mapa.

Nosso Mapa Contextual

A partir do que discutimos no primeiro artigo, podemos montar um mapa contextual mais aprofundado.

O mapa contextual apresentado neste artigo não é sua versão final, definitiva ou mais eficiente, e sim uma das suas iterações que pode e deve ser aperfeiçoada.

  • Meta: contexto externo referente ao ambiente do Instagram e Facebook.
  • IdentityAndAccess: é o contexto de autenticação e autorização. Tudo referente a como os usuários irão se autenticar na nossa aplicação está neste contexto.
  • Customer: é onde as operações dos perfis dos usuários estarão concentradas.
  • Interactions: avaliações e curtidas entre os pontos de interesse e os perfis estão relacionados neste contexto.
  • Imagery: contexto onde processaremos as fotos fornecidas pelos perfis para os pontos de interesse e avaliações.
  • Locations: as regras e manipulações dos pontos de interesse estarão associadas a este contexto.
  • Storage: contexto que abrange os processos para que as imagens sejam salvas e referenciadas.

Pensar no mapa com esses contextos pode parecer contra intuitivo, mas cada um deles tem uma motivação embasada pelos detalhes das regras de negócio que nos foram fornecidos no primeiro artigo.

Por exemplo, o contexto IdentityAndAccess encapsula a autenticação com o contexto externo do Meta. Ao isolar este contexto, conseguimos ter uma melhor manuntenção nesse aspecto, facilitando inclusive a adição de novos métodos de autenticação no futuro sem impactar os outros contextos do sistema.

Os contextos Interactions, Customer, Locations e Imagery são mais intuitivos, por que estão mais próximos da descrição do produto (um aplicativo de recomendação colaborativa de pontos turisticos).

Storage é o contexto que lidará com a indexação e persistência das imagens do nosso sistema, independente de onde essas imagens estejam persistidas (nuvem, localmente, etc).

Contextos Externos

No desenvolvimento de um sistema, por vezes surge a necessidade de se integrar um serviço terceiro ao nosso sistema. O contexto destes serviços pode ser contemplado em nosso mapa como um contexto externo.

Em nosso cenário, precisaremos fazer uma autenticação com o Facebook e Instagram. Para ilustrar este contexto externo, o contexto delimitado Meta foi criado, e nele estará encapsulada a comunicação com essas plataformas (SDKs e implementações).

Relacionamentos entre contextos

Um detalhe adicional que nosso mapa contextual nos provê são símbolos (as letras e palavras) nas pontas ou hastes de cada relacionamento. Cada um destes símbolos descrevem os relacionamentos que estão associados.

Em algumas literaturas, como o “Domain-Driven Design Distilled” de Vaughn Vernon (também mencionado no primeiro artigo), times são atribuídos a cada contexto, e por isso também podemos compreender as relações entre contextos como as relações entre seus times de desenvolvimento e manuntenção.

1. “Upstream” e “Downstream”, ou Produtor e Consumidor

Se analisarmos no mapa o relacionamento entre o contexto Meta e IdentityAndAccess, vemos que eles estão descritos inicialmente com os símbolos “U” e “D”.

Isso se refere aos termos Upstream e Downstream, respectivamente. Eles nos indicam a direção por onde os dados são recebidos, similar ao conceito de Produtor e Consumidor.

Em relações Up/Downstream, o contexto de Upstream influencia o contexto de Downstream, mas o inverso pode não ocorrer. Também indica a direção do relacionamento.

No nosso caso, definimos Upstream como o Meta, que é o contexto externo que detém as informações que precisamos, e Downstream como o IdentityAndAccess, que é o cliente das informações vindas do outro contexto.

2. “Published Language” e “Conformist”

No relacionamento acima, também conseguimos verificar os símbolos “PL” e “CF”, referentes aos termos Published Language e Conformist.

O contexto com símbolo de Published Language (PL, na tradução do livro, Linguagem Publicada) indica que ele contém uma linguagem bem documentada, que pode ser compartilhada e utilizada entre os contextos relacionados.

O contexto Meta tem esse símbolo por que utilizaremos o SDK e API de suas plataformas, que estão extensivamente documentadas em seus repositórios.

Um contexto com o símbolo de Conformist (CF, na tradução do livro, Conformista) adere diligentemente ao modelo do contexto mais acima.

No nosso contexto IdentityAndAccess, utilizaremos a API e SDK do contexto Meta, e por isso estaremos sendo conformistas com relação a comunicação com o contexto acima.

3. Anti-Corruption Layer

Agora olhando para a relação entre IdentityAndAccess e Customer, temos o símbolo “ACL”, indicando que na ponta do Customer temos uma Anti-Corruption Layer (em tradução livre, Camada de Anticorrupção).

O termo provém de um padrão que cria uma fachada na comunicação entre sistemas ou serviços, que traduz e normaliza os dados externos, centralizando possíveis refatorações caso os serviços externos modifiquem o formato dos dados passados.

Embora o padrão possa ser implementado de maneiras variadas, quando usamos este símbolo no mapa, indicamos que há a necessidade de normalizar os dados oriundos da outra ponta da relação (no nosso caso, os dados de IdentityAndAccess).

A Camada de Anticorrupção indica que o contexto precisa implementar uma maneira de processar os dados recebidos em um formato normalizado.

O Customer recebe as informações do IdentityAndAccess, que podem ser afetadas por mudanças nos termos de privacidade, por necessidade de adicionar novas informações resgatadas do contexto externo ou por um update de versão que contém uma mudança no contrato.

A camada de anticorrupção impede que tais modificações precisem ser replicadas no código que o implementa.

4. Partnership

As relações de Imagery e Interactions com Locations é descrita com o símbolo Partnership. Além disso, algo que é importante notar também é que essas relações são as únicas que não tem os símbolos de Up/Downstream.

Indica que não existe uma relação de produtor/consumidor entre os contextos, e todos os envolvidos nessa relação devem ser modelados, construídos e aprimorados em conjunto para se atenderem mutuamente.

Outras relações não mencionadas

Além das relações que descrevemos no nosso mapa contextual, existem outras que não mencionamos aqui.

Michael Plöd, autor do “Hands-on Domain-driven Design — by example”, documentou os relacionamentos entre contextos em seu repositório sobre mapeamento de contextos, e com certeza é uma ótima leitura para se aprofundar um pouco mais nessas relações.

Para listar, essas são algumas das relações e símbolos que não foram incorporadas no nosso mapa contextual:

  • OHS — Open-Host Service
  • SK — Shared Kernel
  • SW — Separate Ways

Conclusão

Chegamos ao final de mais um artigo! Passamos por mais uma das grandes etapas da metodologia DDD e construimos um mapa contextual que está de acordo com a nossa linguagem onipresente.

No nosso próximo artigo, iremos detalhar nossos maiores contextos, com um processo descrito pelo Eric Evans como a destilação de um domínio em núcleos.

Nos vemos no terceiro e último artigo da nossa série!

Contatos

Fontes