Introdução Link para o cabeçalho

O acrônimo SOLID representa cinco princípios fundamentais da programação orientada a objetos que ajudam a criar sistemas mais manuteníveis, escaláveis e flexíveis. Esses princípios são:

  • Single Responsibility Principle (Princípio da Responsabilidade Única)
  • Open/Closed Principle (Princípio Aberto/Fechado)
  • Liskov Substitution Principle (Princípio da Substituição de Liskov)
  • Interface Segregation Principle (Princípio da Segregação de Interfaces)
  • Dependency Inversion Principle (Princípio da Inversão de Dependência)

Vamos ver exemplos práticos em PHP.


1. Single Responsibility Principle (SRP) Link para o cabeçalho

👉 Uma classe deve ter apenas uma responsabilidade.

❌ Sem SRP Link para o cabeçalho

<?php
class Usuario {
    public function cadastrar($dados) {
        echo "Cadastrando usuário...";
    }

    public function enviarEmailBoasVindas($email) {
        echo "Enviando email de boas-vindas...";
    }
}
  • Problema: A classe Usuario cuida tanto do cadastro quanto do envio de e-mail.

✅ Com SRP Link para o cabeçalho

<?php
class Usuario {
    public function cadastrar($dados) {
        echo "Cadastrando usuário...";
    }
}

class EmailService {
    public function enviarBoasVindas($email) {
        echo "Enviando email de boas-vindas...";
    }
}
  • Agora cada classe tem uma única responsabilidade.

2. Open/Closed Principle (OCP) Link para o cabeçalho

👉 Classes devem estar abertas para extensão e fechadas para modificação.

❌ Sem OCP Link para o cabeçalho

<?php
class Relatorio {
    public function gerar($tipo) {
        if ($tipo == 'pdf') {
            echo "Gerando PDF...";
        } elseif ($tipo == 'excel') {
            echo "Gerando Excel...";
        }
    }
}
  • Problema: Para adicionar novos formatos, precisamos alterar a classe.

✅ Com OCP Link para o cabeçalho

<?php
interface Relatorio {
    public function gerar($dados);
}

class RelatorioPDF implements Relatorio {
    public function gerar($dados) {
        echo "Gerando PDF...";
    }
}

class RelatorioExcel implements Relatorio {
    public function gerar($dados) {
        echo "Gerando Excel...";
    }
}
  • Podemos adicionar novos formatos sem modificar código existente.

3. Liskov Substitution Principle (LSP) Link para o cabeçalho

👉 Subtipos devem poder substituir seus tipos base sem quebrar o sistema.

❌ Violando LSP Link para o cabeçalho

<?php
class Ave {
    public function voar() {
        echo "Voando...";
    }
}

class Pinguim extends Ave {
    public function voar() {
        throw new Exception("Pinguins não voam!");
    }
}
  • Problema: O Pinguim não pode substituir a classe base sem quebrar o contrato.

✅ Com LSP Link para o cabeçalho

<?php
interface Ave {
    public function locomover();
}

class Andorinha implements Ave {
    public function locomover() {
        echo "Voando...";
    }
}

class Pinguim implements Ave {
    public function locomover() {
        echo "Andando...";
    }
}
  • Agora qualquer subtipo pode substituir o tipo base sem problemas.

4. Interface Segregation Principle (ISP) Link para o cabeçalho

👉 Interfaces específicas são melhores do que interfaces grandes e genéricas.

❌ Sem ISP Link para o cabeçalho

<?php
interface Funcionario {
    public function programar();
    public function desenhar();
    public function testar();
}

class Programador implements Funcionario {
    public function programar() { echo "Programando..."; }
    public function desenhar() { / não faz sentido / }
    public function testar() { / não faz sentido / }
}
  • Problema: O programador é obrigado a implementar métodos que não usa.

✅ Com ISP Link para o cabeçalho

<?php
interface Programador {
    public function programar();
}

interface Designer {
    public function desenhar();
}

interface Tester {
    public function testar();
}

class Dev implements Programador {
    public function programar() { echo "Programando..."; }
}
  • Cada interface é específica e evita métodos desnecessários.

5. Dependency Inversion Principle (DIP) Link para o cabeçalho

👉 Dependa de abstrações, não de implementações concretas.

❌ Sem DIP Link para o cabeçalho

<?php
class MySQL {
    public function salvar($dados) {
        echo "Salvando no MySQL...";
    }
}

class UsuarioService {
    private MySQL $db;

    public function construct() {
        $this->db = new MySQL();
    }

    public function cadastrar($dados) {
        $this->db->salvar($dados);
    }
}
  • Problema: O serviço depende diretamente de uma implementação específica.

✅ Com DIP Link para o cabeçalho

<?php
interface BancoDeDados {
    public function salvar($dados);
}

class MySQL implements BancoDeDados {
    public function salvar($dados) {
        echo "Salvando no MySQL...";
    }
}

class PostgreSQL implements BancoDeDados {
    public function salvar($dados) {
        echo "Salvando no PostgreSQL...";
    }
}

class UsuarioService {
    private BancoDeDados $db;

    public function construct(BancoDeDados $db) {
        $this->db = $db;
    }

    public function cadastrar($dados) {
        $this->db->salvar($dados);
    }
}
  • Agora podemos trocar o banco sem alterar o serviço.

🎯 Conclusão Link para o cabeçalho

Este artigo mostrou como aplicar cada princípio do SOLID em PHP com exemplos práticos.

  • SRP: uma classe, uma responsabilidade.
  • OCP: aberto para extensão, fechado para modificação.
  • LSP: subtipos substituem tipos base sem problemas.
  • ISP: interfaces pequenas e específicas.
  • DIP: dependa de abstrações, não de implementações.