Introdução Link para o cabeçalho

Os princípios do SOLID são fundamentais para quem deseja escrever código orientado a objetos de forma clara, extensível e fácil de manter. Neste artigo, vamos construir um mini sistema de pedidos em PHP aplicando cada um desses princípios. O objetivo é mostrar como sair de uma estrutura rígida e acoplada para uma arquitetura flexível e organizada.


Estrutura do Projeto Link para o cabeçalho

Nosso sistema terá as seguintes responsabilidades:

  • Produto: representa os itens que podem ser adicionados ao pedido.
  • Pedido: agrupa os produtos e calcula o total.
  • Relatório: gera relatórios em diferentes formatos (PDF, Excel).
  • Persistência: salva os relatórios em diferentes meios (Banco de Dados, Arquivo).
  • Serviço de Pedido: orquestra o processo de gerar e salvar relatórios.

Essa separação já reflete o SRP (Single Responsibility Principle): cada classe tem uma responsabilidade única.


Implementação Link para o cabeçalho

Produto e Pedido Link para o cabeçalho

O Produto guarda nome e preço, enquanto o Pedido permite adicionar produtos e calcular o total.
Isso garante que cada classe faça apenas o que lhe compete.

class Produto {
    private string $nome;
    private float $preco;

    public function construct(string $nome, float $preco) {
        $this->nome = $nome;
        $this->preco = $preco;
    }

    public function getNome(): string { return $this->nome; }
    public function getPreco(): float { return $this->preco; }
}

class Pedido {
    private array $produtos = [];

    public function adicionarProduto(Produto $produto) {
        $this->produtos[] = $produto;
    }

    public function getTotal(): float {
        return arraysum(arraymap(fn($p) => $p->getPreco(), $this->produtos));
    }
}

Relatórios Link para o cabeçalho

Aqui aplicamos o OCP (Open/Closed Principle): podemos criar novos formatos de relatório sem modificar código existente, apenas adicionando novas classes que implementam a interface.

interface GeradorRelatorio {
    public function gerar(Pedido $pedido): string;
}

class RelatorioPDF implements GeradorRelatorio {
    public function gerar(Pedido $pedido): string {
        return "Relatório em PDF - Total: " . $pedido->getTotal();
    }
}

class RelatorioExcel implements GeradorRelatorio {
    public function gerar(Pedido $pedido): string {
        return "Relatório em Excel - Total: " . $pedido->getTotal();
    }
}

Persistência Link para o cabeçalho

O mesmo raciocínio vale para persistência: podemos salvar em banco, arquivo ou qualquer outro meio.
Aqui aplicamos ISP (Interface Segregation Principle) e DIP (Dependency Inversion Principle): criamos uma interface específica e o serviço depende dela, não de uma implementação concreta.

interface Persistencia {
    public function salvar(string $conteudo): void;
}

class BancoDeDados implements Persistencia {
    public function salvar(string $conteudo): void {
        echo "Salvando no banco: $conteudo\n";
    }
}

class Arquivo implements Persistencia {
    public function salvar(string $conteudo): void {
        echo "Salvando em arquivo: $conteudo\n";
    }
}

Serviço de Pedido Link para o cabeçalho

O PedidoService orquestra o processo. Ele recebe abstrações (GeradorRelatorio e Persistencia) e não depende de implementações específicas.
Aqui aplicamos fortemente o DIP.

class PedidoService {
    private GeradorRelatorio $gerador;
    private Persistencia $persistencia;

    public function __construct(GeradorRelatorio $gerador, Persistencia $persistencia) {
        $this->gerador = $gerador;
        $this->persistencia = $persistencia;
    }

    public function processar(Pedido $pedido): void {
        $relatorio = $this->gerador->gerar($pedido);
        $this->persistencia->salvar($relatorio);
    }
}

Exemplo de Uso Link para o cabeçalho

$produto1 = new Produto("Notebook", 3500);
$produto2 = new Produto("Mouse", 150);

$pedido = new Pedido();
$pedido->adicionarProduto($produto1);
$pedido->adicionarProduto($produto2);

$gerador = new RelatorioPDF();
$persistencia = new BancoDeDados();

$service = new PedidoService($gerador, $persistencia);
$service->processar($pedido);

Benefícios do Projeto Link para o cabeçalho

  • SRP: cada classe tem uma responsabilidade única.
  • OCP: novos relatórios ou formas de persistência podem ser adicionados sem alterar código existente.
  • LSP: qualquer implementação de GeradorRelatorio ou Persistencia pode substituir outra sem quebrar o sistema.
  • ISP: interfaces específicas evitam métodos desnecessários.
  • DIP: o serviço depende de abstrações, permitindo fácil troca de implementações.

Conclusão Link para o cabeçalho

Este mini projeto mostra como aplicar todos os princípios do SOLID em conjunto.
O resultado é um sistema simples, mas altamente extensível: podemos adicionar novos formatos de relatório (JSON, XML) ou novas formas de persistência (API, Cloud) sem alterar o código já existente.