No desenvolvimento de software, especialmente quando aplicamos Domain-Driven Design (DDD), frequentemente nos deparamos com dois conceitos importantes: domínio anêmico e domínio rico.
Compreender a diferença entre eles é fundamental para criar aplicações mais robustas e expressivas.
O que é um Domínio Anêmico?
Um domínio anêmico é caracterizado por classes que contêm apenas dados (getters e setters) sem comportamento de negócio. Toda a lógica de negócio fica concentrada em serviços externos às entidades do domínio.
Exemplo de Domínio Anêmico
// Entidade anêmica - apenas dados
public class ContaBancaria
{
public string Numero { get; set; }
public decimal Saldo { get; set; }
public string Titular { get; set; }
}
// Toda lógica de negócio fica no serviço
public class ContaBancariaService
{
public void Sacar(ContaBancaria conta, decimal valor)
{
if (valor <= 0)
{
throw new ArgumentException("Valor deve ser positivo");
}
if (conta.Saldo < valor)
{
throw new ArgumentException("Saldo insuficiente");
}
conta.Saldo -= valor;
}
public void Depositar(ContaBancaria conta, decimal valor)
{
if (valor <= 0)
{
throw new ArgumentException("Valor deve ser positivo");
}
conta.Saldo += valor;
}
public void Transferir(ContaBancaria contaOrigem, ContaBancaria contaDestino, decimal valor)
{
Sacar(contaOrigem, valor);
Depositar(contaDestino, valor);
}
}
O que é um Domínio Rico?
Um domínio rico é caracterizado por classes que encapsulam tanto dados quanto comportamentos relevantes ao negócio. As entidades possuem métodos que representam ações do domínio e mantêm sua própria consistência.
Exemplo de Domínio Rico
// Entidade rica - dados + comportamento
public class ContaBancaria
{
private readonly string _numero;
private decimal _saldo;
private readonly string _titular;
public ContaBancaria(string numero, string titular)
{
if (string.IsNullOrWhiteSpace(numero))
{
throw new ArgumentException("Número da conta é obrigatório");
}
if (string.IsNullOrWhiteSpace(titular))
{
throw new ArgumentException("Titular é obrigatório");
}
_numero = numero;
_titular = titular;
_saldo = 0m;
}
public void Sacar(decimal valor)
{
ValidarValorPositivo(valor);
if (_saldo < valor)
{
throw new InvalidOperationException("Saldo insuficiente para saque");
}
_saldo -= valor;
}
public void Depositar(decimal valor)
{
ValidarValorPositivo(valor);
_saldo += valor;
}
public void Transferir(ContaBancaria contaDestino, decimal valor)
{
if (contaDestino == null)
{
throw new ArgumentNullException(nameof(contaDestino));
}
Sacar(valor);
contaDestino.Depositar(valor);
}
public bool PodeEfetuarSaque(decimal valor)
{
return valor > 0 && _saldo >= valor;
}
private void ValidarValorPositivo(decimal valor)
{
if (valor <= 0)
{
throw new ArgumentException("Valor deve ser positivo");
}
}
// Propriedades apenas para consulta (somente leitura)
public string Numero => _numero;
public decimal Saldo => _saldo;
public string Titular => _titular;
}
Principais Diferenças
Aspecto | Domínio Anêmico | Domínio Rico |
---|---|---|
Localização da Lógica | Nos serviços | Nas próprias entidades |
Encapsulamento | Baixo | Alto |
Expressividade | Menor | Maior |
Consistência | Dependente de código externo | Auto-mantida |
Testabilidade | Requer testes de integração | Permite testes unitários isolados |
Vantagens e Desvantagens
Domínio Anêmico
Vantagens:
- Simplicidade inicial
- Flexibilidade para mudanças
- Familiar para desenvolvedores acostumados com programação procedural
Desvantagens:
- Violação do princípio de encapsulamento
- Lógica de negócio espalhada pela aplicação
- Dificuldade de manutenção em projetos complexos
- Maior risco de inconsistências
Domínio Rico
Vantagens:
- Melhor encapsulamento
- Código mais expressivo e legível
- Consistência garantida pela própria entidade
- Facilita testes unitários
- Alinhado com princípios de orientação a objetos
Desvantagens:
- Curva de aprendizado maior
- Pode ser excessivo para domínios muito simples
- Requer mais planejamento inicial
Embora o domínio anêmico possa parecer mais simples inicialmente, o domínio rico oferece benefícios significativos em termos de manutenibilidade, testabilidade e expressividade do código. A escolha entre as abordagens deve considerar a complexidade do domínio, a maturidade da equipe e os objetivos do projeto.
O importante é estar ciente das implicações de cada abordagem e fazer uma escolha consciente, sempre buscando evoluir em direção a um modelo de domínio mais rico conforme a aplicação cresce em complexidade.
Top comments (0)