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.