Sete arquivos pra salvar um cadastro
Peguei um projeto uma vez pra fazer uma alteração pequena: adicionar o campo "telefone secundário" no cadastro de cliente. Coisa de dez minutos, né?
Uma hora e meia depois eu tinha mexido em: a entidade Cliente, o value object Telefone, o DTO de entrada, o mapper que traduz DTO pra entidade, a interface do repositório, a implementação Eloquent do repositório, o use case AtualizarClienteUseCase, e o request do controller.
Oito arquivos. Pra um campo de texto que vai direto pra uma coluna varchar.
O sistema não fazia nada de mirabolante com esse cliente. Cadastrava, listava, editava, apagava. Um CRUD. Mas estava vestido com o terno de um sistema bancário.
Já pegou um projeto assim? Ou — pergunta mais desconfortável — já escreveu um?
O que parece sofisticação e é só cerimônia
Olha o caminho que um POST /clientes percorria naquele projeto:
// 1. Controller recebe e converte pra DTO
$dto = new CriarClienteDTO(
nome: $request->nome,
email: $request->email,
telefone: $request->telefone,
);
// 2. Use case recebe o DTO
$useCase->executar($dto);
// 3. Dentro do use case: DTO vira entidade de domínio
$cliente = new ClienteEntity(
nome: new Nome($dto->nome),
email: new Email($dto->email),
telefone: new Telefone($dto->telefone),
);
// 4. Repositório recebe a entidade
$this->repositorio->salvar($cliente);
// 5. Dentro do repositório: entidade vira Model
$model = new ClienteModel();
$model->nome = $cliente->nome->valor();
$model->email = $cliente->email->valor();
$model->telefone = $cliente->telefone->valor();
$model->save();
// 6. E aí volta tudo, agora no sentido contrário 🙃
Cinco traduções do mesmo dado. Nome vira Nome, Nome vira string de novo, string vira coluna.
Agora a pergunta honesta: qual bug isso evitou? Qual regra de negócio ficou protegida? Nesse projeto, nenhuma. O ClienteEntity era um saco de propriedades sem nenhum comportamento — exatamente o que a gente acusa de "modelo anêmico", só que espalhado em quatro camadas.
DDD nunca foi sobre pastas
Aqui mora a confusão. A maior parte do que a galera chama de DDD é a parte tática: entidade, value object, agregado, repositório, use case. É a parte fácil de copiar, porque é estrutura de pasta.
Só que o DDD é sobre a parte estratégica: entender o negócio a fundo, conversar com quem trabalha nele, descobrir que "pedido" pro pessoal do estoque não é a mesma coisa que "pedido" pro financeiro, e desenhar fronteiras a partir disso. Linguagem ubíqua, contextos delimitados.
A estrutura de pastas é consequência disso. Não substituto.
Quando você copia só as pastas, o que sobra é o custo — mais arquivos, mais indireção, mais tempo pra qualquer mudança — sem o benefício, que seria um código que fala a língua do negócio.
A régua: complexidade de dado ou complexidade de regra?
A pergunta que eu faço hoje antes de montar qualquer camada:
Esse dado tem regra ou só tem formulário?
Se o fluxo é "recebe do form, valida formato, salva no banco, mostra numa listagem", isso é complexidade de dado. Laravel já resolve isso lindamente com Form Request, Eloquent e Resource. Adicionar camada aí só aumenta a distância entre você e o varchar.
Agora, se o fluxo é "recebe a solicitação, verifica se o cliente tem limite, calcula juros conforme a modalidade, aplica desconto de fidelidade, agenda a cobrança e emite o título" — aí é complexidade de regra. É aqui que separar as coisas te salva, porque a regra vive mais tempo que o framework e muda por motivos diferentes.
E o ponto que quase ninguém fala: os dois convivem no mesmo projeto. Não precisa escolher.
Como fica na prática
O CRUD continua CRUD. Sem culpa nenhuma:
class ClienteController extends Controller
{
public function store(StoreClienteRequest $request)
{
$cliente = Cliente::create($request->validated());
return new ClienteResource($cliente);
}
}
Três linhas. Todo mundo entende, inclusive o dev que entrar no time semana que vem.
O que tem regra ganha uma Action: o caminho do meio que resolve 90% dos casos.
final class AprovarEmprestimo
{
public function __invoke(Emprestimo $emprestimo, User $analista): void
{
// aqui mora a regra, isolada e testável, sem quatro camadas
}
}
E as peças táticas você usa avulso, onde valem a pena. Value Object pra CPF e Dinheiro, Enum pra status, DTO na fronteira de integração. Não é pacote fechado — dá pra pegar só as ferramentas que resolvem o seu problema.
A pegadinha: "mas e quando o projeto crescer?"
Esse é o argumento que eu mais ouço. E ele tem um erro escondido: assume que refatorar depois é mais caro do que carregar a estrutura desde o começo.
Quase nunca é. Transformar um controller gordo em Action é trabalho de uma tarde, e você faz isso sabendo qual é a regra de verdade, porque o negócio já se revelou.
O contrário é que dói: desmontar uma arquitetura de quatro camadas que ninguém entende e que já espalhou tradução de dado por trinta arquivos. Aí é semana, não tarde.
E tem o custo que não aparece no gráfico: cada dev novo no time leva três semanas pra fazer o primeiro CRUD, porque precisa aprender o dialeto local antes de escrever a primeira linha.
Bônus: o teste do "conta pro estagiário"
Antes de adicionar uma camada, tenta explicar em voz alta pra alguém que acabou de chegar qual problema aquilo resolve.
Se a resposta sair como "é pra desacoplar do framework" ou "é boa prática", segura a onda. Não é justificativa, é slogan.
Se a resposta for "porque a regra de cálculo de comissão muda por estado e a gente precisa testar as 27 combinações sem tocar no banco" — aí sim. Isso é um problema concreto, e a camada tem endereço.
Antes de você fechar a aba
Não estou dizendo que DDD é ruim. Em domínio complexo de verdade, com regra de negócio que muda toda semana e gente do negócio discutindo termo por termo, ele é o que segura o sistema em pé.
O que eu tô dizendo é que arquitetura é resposta a um problema. Sem o problema, ela é só custo com aparência de sofisticação.
Cadastro de cliente não precisa de camada anticorrupção. Precisa de Cliente::create().
E aí, você já pegou (ou construiu) um projeto vestido pra uma complexidade que ele não tinha? Ou é do time que acha que camada nunca é demais? Vem discutir nos comentários — esse tema divide a comunidade ao meio e eu quero ouvir os dois lados. 🍿
Top comments (0)