SOLID: Inversão de Dependências (Parte 5)
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”.