Princípios SOLID em PHP: aplicação avançada e exemplos práticos

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

Introdução: Por que SOLID não é apenas um dogma, mas uma ferramenta

A maioria dos desenvolvedores sabe que SOLID são cinco princípios da programação orientada a objetos: Responsabilidade Única (Single Responsibility), Aberto/Fechado (Open-Closed), Substituição de Liskov (Liskov Substitution), Segregação de Interface (Interface Segregation) e Inversão de Dependência (Dependency Inversion). No entanto, na prática, a compreensão muitas vezes se resume a seguir regras mecanicamente. Neste artigo, iremos mais longe: analisaremos cenários avançados de aplicação do SOLID em PHP, consideraremos antipadrões que violam os princípios e mostraremos como a refatoração com SOLID torna o código flexível e testável.

O material é voltado para desenvolvedores de nível Pleno+ e Sênior que já programam em PHP e desejam melhorar a arquitetura de seus projetos.



1. Princípio da Responsabilidade Única (SRP): quando a classe "sabe demais"

A formulação clássica: "Uma classe deve ter apenas um motivo para mudar". Em um nível avançado, é importante entender que "motivo para mudar" é um requisito de negócio. Se sua classe muda devido a alterações nas regras de validação, formato de saída ou lógica de persistência, isso é uma violação do SRP.



Exemplo de violação (God Object)

class OrderProcessor {    public function process(array $data): void {        // 1. Validação dos dados        if (empty($data['user_id']) || empty($data['items'])) {            throw new InvalidArgumentException('Invalid order data');        }                // 2. Cálculo do total        $total = 0;        foreach ($data['items'] as $item) {            $total += $item['price'] * $item['quantity'];        }                // 3. Persistência no banco de dados        $sql = "INSERT INTO orders (user_id, total, status) VALUES (?, ?, 'pending')";        // ... execução da consulta                // 4. Envio de e-mail        mail($data['user_email'], 'Order confirmation', "Total: $total");    }}


Refatoração com SRP

Dividimos em três classes com áreas de responsabilidade claras:

class OrderValidator {    public function validate(array $data): void {        if (empty($data['user_id']) || empty($data['items'])) {            throw new InvalidArgumentException('Invalid order data');        }    }}

class OrderCalculator { public function calculateTotal(array $items): float { return array_reduce($items, function ($carry, $item) { return $carry + $item['price'] * $item['quantity']; }, 0.0); }}

class OrderRepository { public function save(int $userId, float $total, string $status = 'pending'): int { // Lógica de persistência no banco de dados return 42; // ID do pedido }}

class OrderProcessor { public function __construct( private OrderValidator $validator, private OrderCalculator $calculator, private OrderRepository $repository, private Mailer $mailer ) {} public function process(array $data): void { $this->validator->validate($data); $total = $this->calculator->calculateTotal($data['items']); $orderId = $this->repository->save($data['user_id'], $total); $this->mailer->send($data['user_email'], 'Order #' . $orderId); }}


2. Princípio Aberto/Fechado (OCP): extensão sem modificação

A essência do OCP: as classes devem estar abertas para extensão, mas fechadas para modificação. Na prática, isso significa usar polimorfismo e abstrações em vez de construções condicionais.



Violação do OCP: switch-case para cada novo tipo

class PaymentProcessor {    public function pay(string $type, float $amount): void {        switch ($type) {            case 'credit_card':                // processamento de cartão                break;            case 'paypal':                // processamento PayPal                break;            // Ao adicionar um novo tipo — alteramos a classe!        }    }                

Blogs

Book Recommendations