SOLID: Inversão de Dependências (Parte 5)

·2 min de leitura

Fechando o SOLID com o “D”

O Dependency Inversion Principle (DIP) costuma ser resumido em duas frases. A primeira diz que módulos de alto nível não devem depender de módulos de baixo nível; ambos devem depender de abstrações. A segunda diz que abstrações não devem depender de detalhes; detalhes devem depender de abstrações.

Tradução prática: seu domínio não deve ficar refém de MySQL, cURL, SDK de terceiros, etc.

DIP não é só “usar interface”

Colocar interface em tudo sem necessidade vira teatro. DIP faz sentido quando há variação real ou quando você quer proteger o núcleo de infraestrutura.

Exemplo na prática: notificações

Ruim: alto nível preso ao SMTP concreto

<?php

declare(strict_types=1);

final class BillingService
{
    public function chargeCustomer(): void
    {
        // ...
        mail('a@b.com', 'Cobrança', 'ok'); // detalhe de infraestrutura infiltrado
    }
}

Explicação: testes dependem de ambiente; trocar canal (SMS/push) dói.

Melhor: depender de abstração

<?php

declare(strict_types=1);

interface CustomerNotifier
{
    public function notifyBillingReceipt(CustomerId $customerId): void;
}

final readonly class BillingService
{
    public function __construct(private CustomerNotifier $notifier) {}

    public function chargeCustomer(CustomerId $customerId): void
    {
        // regra de cobrança...
        $this->notifier->notifyBillingReceipt($customerId);
    }
}

final readonly class SmtpCustomerNotifier implements CustomerNotifier
{
    public function notifyBillingReceipt(CustomerId $customerId): void
    {
        // integração SMTP real
    }
}

Uso:

$notifier = new SmtpCustomerNotifier();
$billing  = new BillingService($notifier);

$billing->chargeCustomer(new CustomerId('cust-123'));

Explicação: BillingService conhece o papel (CustomerNotifier), não o SMTP. Detalhe fica na borda.

Inversão vs injeção

Aqui vale uma distinção importante. DIP é um princípio de desenho (direção das dependências). Injeção de dependência é um mecanismo (passar dependências de fora, construtor, método, container). Eles andam juntos, mas não são a mesma coisa.

Conclusão

DIP coloca abstrações no meio e empurra detalhes para fora. Isso melhora testabilidade, evolução e clareza do que é “regra” vs “integração”.