Domain-Driven Design em PHP: domine a complexidade com DDD

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Domain-Driven Design em PHP: transforme o caos em ordem

\n\n

Você já sentiu que seu projeto PHP está crescendo como uma bola de neve? No começo, tudo é simples: alguns controladores, um model, algumas consultas ao banco. Mas depois de seis meses, você está afogado em código espaguete, onde a lógica de negócio está espalhada pelos serviços, e uma simples mudança de requisito leva uma semana.

\n\n

Familiar? Bem-vindo ao clube. Mas a boa notícia é: Domain-Driven Design (DDD) não é uma teoria abstrata dos livros grossos do Eric Evans. É uma ferramenta prática que realmente ajuda a escrever código PHP compreensível tanto para os negócios quanto para os desenvolvedores.

\n\n

Neste artigo, vamos explorar o DDD na prática. Sem enrolação, com exemplos reais em PHP. Você vai aprender como implementar DDD no seu projeto sem quebrar a cabeça e sem reescrever tudo do zero. Vamos nessa!

\n\n

O que é Domain-Driven Design e por que você precisa dele como dev PHP?

\n\n

Imagine que você está criando um e-commerce. Você tem descontos, carrinho, pedidos. A lógica de negócio: "desconto não acumula com cupom", "pedido não pode ser cancelado após o envio". Se você guarda essa lógica nos controladores ou a espalha pelos models do ORM, mais cedo ou mais tarde vai se perder.

\n\n

DDD é uma abordagem que coloca o domínio de negócio (sua área de conhecimento) no centro do desenvolvimento. Em vez de pensar em tabelas e consultas SQL, você pensa em entidades, valores e eventos.

\n\n

Para PHP, isso é especialmente relevante. A linguagem é flexível, mas sem uma arquitetura clara, os projetos rapidamente viram "legado". O DDD fornece uma estrutura que permanece legível mesmo depois de um ano.

\n\n

Design Estratégico vs Design Tático

\n\n

O DDD se divide em duas grandes partes:

\n
    \n
  • Design Estratégico — é o mapa do seu projeto. Você identifica Contextos Delimitados (Bounded Contexts) e constrói uma Linguagem Ubíqua (Ubiquitous Language). Por exemplo, no contexto "Catálogo", um produto é apenas um conjunto de características; já no contexto "Pedido", ele é uma unidade com preço e quantidade.
  • \n
  • Design Tático — são os blocos de construção: Entity, Value Object, Aggregate, Repository, Domain Service, Domain Event. Vamos focar neles.
  • \n
\n\n

Design Tático em PHP: os blocos do DDD

\n\n

Vamos ver como os principais padrões do DDD se parecem em PHP. Esqueça o ActiveRecord do Laravel ou Symfony — aqui estamos construindo um modelo independente de framework.

\n\n

1. Entity (Entidade)

\n

Uma entidade é um objeto que possui um identificador único e muda ao longo do tempo. Por exemplo, User ou Order. Comparamos entidades pelo ID, não pelos campos.

\n\n
<?php\n\ndeclare(strict_types=1);\n\nnamespace App\\Domain\\Entity;\n\nuse App\\Domain\\ValueObject\\UserId;\nuse App\\Domain\\ValueObject\\Email;\n\nclass User\n{\n    public function __construct(\n        private UserId $id,\n        private string $name,\n        private Email $email\n    ) {}\n\n    public function getId(): UserId\n    {\n        return $this->id;\n    }\n\n    public function changeEmail(Email $newEmail): void\n    {\n        // Aqui pode haver lógica de negócio: verificar se o email já não está em uso\n        $this->email = $newEmail;\n    }\n\n    public function getEmail(): Email\n    {\n        return $this->email;\n    }\n}\n
\n\n

2. Value Object (Objeto de Valor)

\n

Um Value Object é um objeto imutável que é definido por seus atributos, não por um identificador. Dois Value Objects são iguais se todos os seus campos coincidirem. Clássicos: Money, Email, Address.

\n\n
<?php\n\ndeclare(strict_types=1);\n\nnamespace App\\Domain\\ValueObject;\n\nclass Email\n{\n    private string $value;\n\n    public function __construct(string $value)\n    {\n        if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {\n            throw new \\InvalidArgumentException('Endereço de email inválido');\n        }\n        $thi                

Blogs

Book Recommendations