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
GeradorRelatorioouPersistenciapode 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.