DEV Community

Danilo O. Pinheiro, dopme.io
Danilo O. Pinheiro, dopme.io

Posted on

Entendendo o DDD Antes do Código

Louvai ao Senhor dos senhores; porque a sua benignidade dura para sempre. Aquele que só faz grandes maravilhas; porque a sua benignidade dura para sempre. Salmos 136:3,4

Em projetos de software, é comum vermos aplicações bem escritas tecnicamente, mas que falham em entregar valor real ao negócio. Muitas vezes, o problema não está na tecnologia usada, mas na distância entre desenvolvedores e especialistas do domínio. O Domain-Driven Design (DDD) surgiu para resolver exatamente isso.

Neste artigo, você vai aprender os fundamentos do DDD e como começar a aplicar na prática com .NET, mesmo em projetos pequenos ou médios.


🎯 O que é Domain-Driven Design?

DDD é uma abordagem de desenvolvimento de software focada no domínio do problema. Ou seja, antes de pensar em banco de dados, API, framework ou arquitetura, o foco está em entender profundamente as regras de negócio com o apoio de especialistas da área (o famoso Domain Expert).

🧩 O objetivo é refletir o domínio do problema no próprio código-fonte, tornando-o expressivo e alinhado com o negócio.


🔍 Por que usar DDD?

  • Evita soluções genéricas que não resolvem o problema real
  • Organiza o projeto com base em regras de negócio, não só por camadas técnicas
  • Cria um modelo rico e reutilizável
  • Facilita a comunicação entre devs e especialistas do negócio
  • Base para evolução arquitetural (Hexagonal, Clean, Microserviços)

📚 Os Conceitos Básicos do DDD

✅ Entidade

Um objeto que possui identidade própria, mesmo que seus atributos mudem.

public class Cliente { public Guid Id { get; private set; } public string Nome { get; private set; } public Cliente(string nome) { Id = Guid.NewGuid(); Nome = nome; } } 
Enter fullscreen mode Exit fullscreen mode

✅ Value Object

Um objeto sem identidade própria, representado apenas pelos seus atributos.

public class CPF { public string Numero { get; } public CPF(string numero) { if (!Validar(numero)) throw new Exception("CPF inválido"); Numero = numero; } private bool Validar(string numero) => numero.Length == 11; } 
Enter fullscreen mode Exit fullscreen mode

✅ Aggregate e Root

Um Aggregate é um conjunto de entidades e value objects que formam uma unidade de consistência. O Aggregate Root é a entidade que controla esse conjunto.

public class Pedido : AggregateRoot { public Guid Id { get; private set; } private List<ItemPedido> _itens = new(); public IReadOnlyCollection<ItemPedido> Itens => _itens; public void AdicionarItem(string produto, int quantidade) { _itens.Add(new ItemPedido(produto, quantidade)); } } 
Enter fullscreen mode Exit fullscreen mode

✅ Repositório

Abstrai o acesso a dados, fornecendo uma interface orientada ao domínio.

public interface IPedidoRepository { Task<Pedido> ObterPorIdAsync(Guid id); Task AdicionarAsync(Pedido pedido); } 
Enter fullscreen mode Exit fullscreen mode

✅ Serviço de Domínio

Contém regras de negócio que não pertencem diretamente a uma entidade.

public class CalculadoraDeFrete { public decimal Calcular(Pedido pedido) { return pedido.Itens.Count * 10; } } 
Enter fullscreen mode Exit fullscreen mode

🗂 Estrutura de Projeto DDD (simples)

src/ ├── Domain/ │ ├── Entidades/ │ ├── ValueObjects/ │ ├── Repositorios/ │ └── Servicos/ │ ├── Application/ │ ├── UseCases/ │ └── DTOs/ │ ├── Infrastructure/ │ ├── Data/ │ └── Implementacoes/ │ └── WebAPI/ └── Controllers/ 
Enter fullscreen mode Exit fullscreen mode

👥 Colaboração com Especialistas do Domínio

Um ponto essencial no DDD é a criação de um Modelo de Domínio em conjunto com pessoas da área de negócio. Isso evita mal-entendidos e garante que o código reflete a realidade.

🗣 A linguagem usada no código deve ser a mesma que o cliente entende: “Cliente”, “Pedido”, “Pagamento”, etc.


🎮 Exemplo Prático: Cadastro de Clientes

Entidade

public class Cliente { public Guid Id { get; private set; } public Nome Nome { get; private set; } public CPF Cpf { get; private set; } public Cliente(Nome nome, CPF cpf) { Id = Guid.NewGuid(); Nome = nome; Cpf = cpf; } } 
Enter fullscreen mode Exit fullscreen mode

Value Object Nome

public class Nome { public string Valor { get; } public Nome(string valor) { if (string.IsNullOrWhiteSpace(valor)) throw new Exception("Nome inválido"); Valor = valor; } } 
Enter fullscreen mode Exit fullscreen mode

🧭 Quando usar DDD?

Projeto DDD é ideal?
CRUD simples ❌ Overkill
Regras de negócio complexas ✅ Sim
Múltiplos domínios (vendas, estoque) ✅ Sim
Times separados por domínio ✅ Sim

🚨 Dicas para Iniciantes

  • Comece simples, sem querer aplicar todos os padrões de uma vez
  • Foque na linguagem ubíqua (ex: Pedido, Produto, Cliente)
  • Evite usar DDD apenas como estrutura de pastas
  • Combine DDD com Clean Architecture e testes de unidade

📘 Recomendação de Leitura


🤝 Conecte-se Comigo

Se você está começando com DDD ou quer evoluir a arquitetura da sua aplicação .NET, vamos trocar experiências:

Top comments (0)