O que é DDD?
- Domain-Driven Design (DDD) é um conjunto de ideias e princípios para modelagem de software.
- Ele possui uma forte influência nas regras de negócio.
- Foi idealizado para manter um padrão linguístico entre as equipes de domínio e técnica.
- DDD não é uma arquitetura.
- Não oferece uma solução pronta (receita de bolo) ou uma solução universal (bala de prata).
- Foi idealizado por Eric Evans em 2003.
Linguagem Onipresente
- Define uma linguagem comum entre os integrantes das equipes de negócio e técnica.
- Nas fronteiras que os delimitam, essa linguagem é absoluta.
- Essas fronteiras são chamadas de contextos delimitados.
Exemplo de Linguagem Onipresente
- O que define a fronteira entre as linguagens onipresentes são os contextos delimitados.
- Não existe nada absoluto; as linguagens onipresentes não devem ser tratadas como algo fixo ou imutável.
- Se o negócio evoluir e houver a necessidade de mudar essa linguagem, uma reunião deve ser realizada imediatamente para discutir essa mudança.
- A linguagem onipresente é definida em conjunto por gerentes, especialistas de domínio e equipe técnica. Nunca se deve criar uma linguagem onipresente sem o consenso dessas partes, pois o acordo comum é o início do sucesso na implementação do DDD.
A PESSOA
seria a linguagem onipresente; é o nome dado a um tipo de entidade ou objeto de valor. No entanto, no mesmo sistema, pode haver outro objeto também chamado PESSOA
, o que pode ser problemático.
Mas, quando delimitamos os contextos, faz mais sentido ter essas duas entidades com o mesmo nome.
Quando temos essas duas entidades dentro de um contexto delimitado, como o contexto de funcionários
e o contexto de clientes
, é possível ter a Pessoa
em ambos os contextos. O contexto vai definir o que essa Pessoa
representa no sistema.
Exemplo de Projeto
Estrutura do Domínio:
MusicCorp.Core.Domain
- /Contexts
- Contexts/Album
- Contexts/Artistas
- Contexts/Clientes
- Contexts/Fornecedores
- Contexts/Pedidos
Os contextos são organizados dessa forma por dois motivos principais. Primeiro, se for necessário dividir o sistema em serviços menores no futuro, os contextos já estarão separados, facilitando a extração de cada um como uma aplicação independente. Essa separação foi planejada desde a estrutura inicial do domínio.
Estrutura de Álbum:
- /Album
- /Album/Entities
- /Album/ValueObjects
O contexto de Album
contém entidades e objetos de valor, representando um domínio real. Tudo dentro deste contexto é construído com base nessa abstração.
Exemplo de Implementação
Classe Base para Álbum:
A classe AlbumBase
é uma classe abstrata que define as propriedades principais de um álbum, permitindo o compartilhamento de informações entre as entidades concretas (filhas) que a herdam.
public abstract class AlbumBase
{
protected AlbumBase(string nomePrincipal, AlbumDetalhes detalhes, AlbumHistoria historia, DateTime dataEntrada)
{
NomePrincipal = nomePrincipal;
Detalhes = detalhes;
Historia = historia;
DataEntrada = dataEntrada;
}
public string NomePrincipal { get; private set; }
public AlbumDetalhes Detalhes { get; private set; }
public AlbumHistoria Historia { get; private set; }
public DateTime DataEntrada { get; private set; }
}
Utilizar classes base é uma boa prática, pois permite o compartilhamento de funcionalidades e propriedades comuns entre as subclasses.
Evite a Obsessão por Tipos Primitivos:
Outro ponto importante é evitar a obsessão por tipos primitivos. Em vez de usar tipos como int
ou string
diretamente, é recomendável criar objetos de valor. Objetos de valor são tipos que encapsulam dados, mas não possuem identidade própria.
Exemplo de Objeto de Valor:
public record AlbumDetalhes
{
public AlbumDetalhes(string nomeOriginal, string descricao, string origem)
{
NomeOriginal = nomeOriginal;
Descricao = descricao;
Origem = origem;
}
public string NomeOriginal { get; init; }
public string Descricao { get; init; }
public string Origem { get; init; }
}
Neste exemplo, AlbumDetalhes
é um objeto de valor que encapsula detalhes do álbum, evitando o uso direto de tipos primitivos como string
.