O padrão de projeto Strategy é um padrão comportamental que permite definir uma família de algoritmos, encapsular cada um deles e torná-los intercambiáveis. Em essência, ele permite que o algoritmo varie independentemente dos clientes que o utilizam.
Em vez de implementar múltiplos comportamentos dentro de uma única classe usando condicionais complexas (if-else ou switch-case), o Strategy propõe extrair cada comportamento para sua própria classe. Isso promove o Princípio Aberto/Fechado (Open/Closed Principle), permitindo adicionar novos comportamentos sem modificar o código existente.
O Problema: O Perigo dos Conditionals Link para o cabeçalho
Imagine um sistema de processamento de pagamentos. Se você tiver um método que verifica o tipo de pagamento e executa uma lógica diferente para cada um, seu código rapidamente se torna difícil de manter:
// Código "sujo" (Anti-pattern)
public function processar($tipo, $valor) {
if ($tipo == 'cartao') {
// lógica complexa de cartão
} elseif ($tipo == 'pix') {
// lógica complexa de pix
} elseif ($tipo == 'boleto') {
// lógica complexa de boleto
}
}
À medida que novos métodos de pagamento surgem, esse método cresce infinitamente, tornando-se uma fonte de erros e difícil de testar.
A Solução: Exemplo em PHP Link para o cabeçalho
Com o Strategy, criamos uma interface comum e implementamos classes específicas para cada comportamento.
1. A Interface Strategy Link para o cabeçalho
Define o contrato que todos os algoritmos devem seguir.
interface MetodoPagamento {
public function pagar(float $valor): string;
}
2. Implementações Concretas Link para o cabeçalho
Cada classe lida com uma estratégia específica.
class PagamentoCartao implements MetodoPagamento {
public function pagar(float $valor): string {
return "Pagamento de R$ {$valor} realizado via Cartão de Crédito.";
}
}
class PagamentoPix implements MetodoPagamento {
public function pagar(float $valor): string {
return "Pagamento de R$ {$valor} realizado via PIX.";
}
}
3. O Contexto Link para o cabeçalho
A classe que utiliza o algoritmo, sem se importar com a implementação interna.
class Checkout {
private MetodoPagamento $metodo;
public function setMetodo(MetodoPagamento $metodo) {
$this->metodo = $metodo;
}
public function finalizar(float $valor) {
echo $this->metodo->pagar($valor);
}
}
// Uso
$checkout = new Checkout();
$checkout->setMetodo(new PagamentoPix());
$checkout->finalizar(150.00); // Saída: Pagamento de R$ 150 realizado via PIX.
$checkout->setMetodo(new PagamentoCartao());
$checkout->finalizar(200.00); // Saída: Pagamento de R$ 200 realizado via Cartão de Crédito.
Vantagens do Strategy Link para o cabeçalho
- Encapsulamento: A lógica de cada algoritmo fica isolada.
- Manutenibilidade: Adicionar um novo método de pagamento requer apenas criar uma nova classe que implementa a interface, sem tocar no código do
Checkout. - Testabilidade: Cada estratégia pode ser testada unitariamente de forma isolada.