1. Além do CRUD: Por que DDD?

A maioria das aplicações de software falha não por falta de tecnologia, mas por falha na compreensão do negócio. Muitas vezes, desenvolvedores focam em tabelas de banco de dados e telas de interface antes de entenderem as regras que governam o problema.

O que é DDD? Domain-Driven Design (Projeto Orientado ao Domínio) é uma abordagem de desenvolvimento de software complexo que foca no domínio central e na lógica do negócio. Foi introduzido por Eric Evans em 2003.

O DDD não é sobre "onde colocar os arquivos", mas sobre como modelar o software para que ele reflita a realidade do negócio. Em projetos de Sistemas de Informação, onde lidamos com KPIs, Dashboards e processos gerenciais, a clareza do domínio é a diferença entre um sistema útil e um "legado instantâneo".

2. Design Estratégico: O "Big Picture"

Antes de escrever classes, precisamos definir as fronteiras do nosso sistema.

Linguagem Ubíqua (Ubiquitous Language)

É um vocabulário comum compartilhado por Especialistas de Negócio e Desenvolvedores. Se o gestor chama um processo de "Ciclo de Apuração", esse nome DEVE estar no código. Evite nomes técnicos como DataProcessManager.

Bounded Context (Contexto Delimitado)

Um sistema grande não possui um único modelo. O termo "Usuário" significa algo diferente para o RH (Colaborador) e para o Financeiro (Pagador). Um Bounded Context define a fronteira onde um termo tem um significado específico e consistente.

Regra de Ouro: Tentar criar um modelo único para toda a empresa ("The Canonical Model") é uma receita para o desastre e acoplamento excessivo.

3. Design Tático: Os Blocos de Construção

Como implementamos o domínio no código .NET?

Entidades

Objetos que possuem uma identidade única que persiste no tempo. Mesmo que todos os atributos mudem, a identidade permanece a mesma.

  • Ex: Funcionario, Projeto, Relatorio.
  • Identificado por um ID (GUID, CPF, etc).

Value Objects (Objetos de Valor)

Objetos definidos apenas por seus atributos. Eles são imutáveis. Se você muda um atributo, você tem um novo objeto.

  • Ex: Endereco, CPF, Dinheiro.
  • Não possuem ID próprio.

Exemplo de Implementação (C#)

// Value Object (Imutável)
public record Dinheiro(decimal Valor, string Moeda);

// Entidade
public class Funcionario {
    public Guid Id { get; private set; } // Identidade
    public string Nome { get; private set; }
    public Dinheiro Salario { get; private set; } // Composição com VO

    public Funcionario(string nome, Dinheiro salario) {
        if (string.IsNullOrWhiteSpace(nome)) throw new DomainException("Nome inválido");
        Id = Guid.NewGuid();
        Nome = nome;
        Salario = salario;
    }

    public void Promover(Dinheiro novoSalario) {
        if (novoSalario.Valor <= Salario.Valor) 
            throw new DomainException("Novo salário deve ser maior");
        Salario = novoSalario;
    }
}

4. Agregados e Raízes de Agregação

Um Agregado é um cluster de objetos associados que tratamos como uma unidade para fins de mudança de dados. Cada agregado tem uma Raiz (Aggregate Root).

As 3 Regras de Ouro dos Agregados:
  1. Proteja as invariantes (regras de negócio) dentro da fronteira do agregado.
  2. Referencie outros agregados apenas pelo seu ID (nunca pelo objeto completo).
  3. Modifique apenas um agregado por transação de banco de dados.

Por que isso importa no Projeto 9? Se você está gerando um Dashboard, ele pode ser um agregado que contém Widgets. Para garantir que o Dashboard não ultrapasse o limite de 10 widgets, essa regra deve estar na Raiz do Agregado (Dashboard).

5. Modelo de Domínio Rico vs. Anêmico

Característica Modelo Anêmico (Anti-padrão) Modelo Rico (DDD)
Onde está a lógica? Em "Services" externos (Classes FuncionarioService). Dentro da própria Entidade ou Value Object.
Estado Getters e Setters públicos para tudo. Setters privados. Mudança de estado via métodos de negócio (ex: FinalizarContrato()).
Validação O objeto pode estar em um estado inválido a qualquer momento. O objeto "nasce" válido e nunca permite transições para estados inválidos.

6. Organização em Camadas (Onion/Clean Architecture)

Para proteger o domínio, organizamos o projeto .NET em camadas concêntricas:

1. Domain (Núcleo)
   - Entidades, Value Objects, Interfaces de Repositório, Domain Services.
   - Dependência: NENHUMA.

2. Application (Orquestração)
   - Use Cases (Casos de Uso), DTOs, Mappers.
   - Dependência: Domain.

3. Infrastructure (Detalhes)
   - Implementação de Repositórios (Entity Framework), Envio de E-mail, APIs externas.
   - Dependência: Application, Domain.

4. WebAPI / Presentation (Entrada)
   - Controllers, Middlewares, Swagger.
   - Dependência: Infrastructure (via DI), Application.

7. Repositórios e Camada de Anticorrupção

Repositórios

Um repositório não é um DAO (Data Access Object). Enquanto o DAO foca em tabelas, o Repositório foca na Coleção de Agregados. Ele é uma interface definida no Domínio e implementada na Infraestrutura.

ACL (Anti-Corruption Layer)

Se o seu sistema precisa ler dados de um sistema legado "bagunçado", você cria uma ACL. Ela traduz os dados horríveis do legado para os seus Value Objects e Entidades limpos, impedindo que a "sujeira" externa contamine seu domínio.

8. Desafio: Modelagem do Projeto 9

Com base no tema do seu grupo (Dashboards Gerenciais), realize os seguintes passos:

  1. Glossário de Domínio: Liste 5 termos que seu grupo usa e defina-os (Linguagem Ubíqua).
  2. Identificação: Escolha um conceito importante (ex: Indicador). Ele é uma Entidade ou um Value Object? Por quê?
  3. Comportamento: Escreva um método que represente uma regra de negócio real (ex: AtualizarMeta()) e quais validações ele deveria ter.
  4. Fronteiras: Identifique um sistema externo (ex: ERP da Empresa) e desenhe como seria a ACL para esse sistema.

Referências para Aprofundamento