github blob

GITHUB BLOG

Fundamentos do Domain-Driven Design

bruno-valerohá 2 meses0 comentários

O Domain-Driven Design é uma metodologia que tem o objetivo de tornar o desenvolvimento de software mais consistente, assertivo e escalável. Ele não tem ligação com padrões de projeto, mas sim com a comunicação e o entendimento das características do negócio e a união dos mesmos com o software. Há três pilares que sustentam a metodologia Domain-Driven Design, que são: a Linguagem Ubíqua, os Domínios ou Bounded Contexts e Context Map.

1 - Linguagem Ubíqua

Os desenvolvedores comumente adotam uma linguagem própria ao desenvolver um software, como por exemplo referenciar qualquer pessoa como "User". Porém cada negócio trata as entidades que o constituem de maneira diferente, chamando as pessoas que entram num ônibus de "Passageiro" e as pessoas que comem num restaurante de "Cliente".

A Linguagem Ubíqua veio para estreitar essa comunicação, ela tem o objetivo de facilitar a troca de informação entre os desenvolvedores do software e os Domain Experts. Isso deve ser feito entendendo a linguagem usada para identificar cada aspecto do negócio e replicando esta linguagem para dentro do software.

Dessa forma tanto os desenvolvedores quanto os integrantes do negócio referenciam as mesmas entidades em um diálogo, diminuindo o risco de maus entendidos e tornando o desenvolvimento mais rápido, assertivo e manutenível.

Domain Experts

São as pessoas que mais entendem o funcionamento prático do negócio, ou seja, aqueles que estão no dia-a-dia lidando com os problemas diretamente. No exemplo do ônibus, os Domain Experts são: o motorista e o cobrador. Já no exemplo do restaurante, são: o caixa, o garçom, a cozinheira, etc.

Em todos esses casos, as pessoas citadas são aquelas que mais entendem as características do negócio, é através delas que será possível se informar sobre a linguagem usada, quais aspectos são relevantes para o funcionamento do negócio, quais precisam de aperfeiçoamento e quais atrapalham.

2 - Domínios ou Bounded Contexts

Através do diálogo com os Domain Experts será possível identificar que o negócio é constituído de setores, ou domínios, ou bounded contexts. Cada domínio tem suas próprias responsabilidades (use cases), entidades (entities), linguagem (linguagem ubíqua) e é independente de outros domínios, podendo funcionar normalmente sem a existência dos demais, porém ainda sim tem a capacidade de se comunicar com outros setores através dos Domain Events.

Entities

Embora o negócio possua uma entidade "Passageiro" ou "Cliente" como exemplificado no trecho sobre Linguagem Ubíqua, ainda sim cada domínio pode tratar esta mesma entidade de maneira diferente.

Por exemplo o domínio de Caixa entende que o Cliente possui uma forma de pagamento e um total a pagar. Já o domínio da Cozinha desconhece essas características, em vez disso ele entende que o cliente tem um pedido, que é apressado ou calmo, que gosta de determinados ingredientes, entre outras características, que muitas das vezes não são interessantes para os demais domínios do negócio.

Use Cases

São as responsabilidades de um domínio, ou seja, os problemas que ele deve resolver. Essas informações também são retiradas a partir do diálogo com um Domain Expert. Eles manipulam uma ou mais Entities do domínio para executar sua função e podem, ou não, disparar um Domain Event dependendo das regras de negócio.

Voltando ao exemplo do restaurante, o domínio de Atendimento pode ter os seguintes use cases:

  • Criar Pedido
  • Deletar Pedido
  • Atualizar Pedido
  • Buscar pedido por ID
  • Buscar pedido por número da mesa
  • Cadastrar Cliente
  • Atualizar Cliente
  • Buscar Cliente por ID

Já o domínio de Caixa pode ter os seguintes use cases:

  • Registrar Forma de Pagamento
  • Deletar Forma de Pagamento
  • Atualizar Forma de Pagamento
  • Buscar Forma de Pagamento por ID do Cliente
  • Buscar Forma de Pagamento por ID
  • Buscar Cliente por ID
  • Cobrar Cliente
  • Cadastrar Cliente
  • Atualizar Cliente
  • Buscar Pedido por ID
  • Marcar Pedido como Pago

E isso se aplica aos demais domínios do negócio

Domain Events

Os Eventos de Domínio permitem a comunicação entre os diversos domínios de um software, por exemplo é através deles que o domínio da Cozinha é informado que há um novo Pedido pendente.

Esta informação deve ser passada sem o contato direto entre o domínio de Atendimento e o domínio da Cozinha, para que cada setor permaneça desacoplado e sejam independentes uns dos ouros. Uma das formas de se atingir isso é através do método Pub/Sub.

3 - Context Map

Depois de definir quais são os domínios do negócio, é necessário dividi-los em três categorias: os Core Domains, os Support Domains e os Generic Domains, isso é essencial para determinar a importância de cada domínio e qual deles deve receber mais atenção. Após isso o Context Map deve ser aplicado que é determinar qual a relação entre os domínios, quais deles devem devem ditar tendências e quais terão que se adaptar a essa tendência gerada.

No exemplo do restaurante, a Cozinha se encaixa nos Core Domains, pois ela é o motivo pelo qual o negócio existe. O Atendimento pode se encaixar nos Suppporting Domains, pois é através dele que todos os outros domínios entrarão em ação. E o Caixa pode se encaixar nos Generic Domais, pois embora seja importante, não é essencial para o funcionamento do negócio.

Domain-Driven Design na Prática

Eu publiquei um projeto meu no GitHub, que tem como objetivo realizar o controle de encomendas de uma transportadora. Em bora não seja um projeto grande, eu implementei a metodologia Domian-Driven Design e Clean Architecture em sua construção, pois isto fazia parte do desafio proposto pela Rocketseat, a instituição de ensino ao qual participo.

O projeto foi desenvolvido em NodeJS usando o framework NestJS, e além dos conceitos citados neste artigo, eu também usei alguns padrões de projeto, como o repository pattern e a invenção de dependência. Confira o desenvolvimento do projeto abaixo:

Fast Feet Api DesafioRocketseat