Strategy - Padrões de Projeto no PHP Artigo

Conheça os cursos gratuitos do WebDevBr! - Inscreva-se!


Este artigo foi publicado a 8 meses, 1 semana, 3 dias atrás.

Uma das minhas soluções favoritas, o Strategy é um padrão de projeto comportamental que muita gente já usou sem saber!

Este padrão de projeto é usado para encapsular seus códigos de forma a facilitar a expanção de recursos de forma organizada e eficiente, a grande diferença entre ele e outros padrões de projeto comportamentais é a forma simples como ele se apresenta.

Imagine que você tem uma loja virtual com várias formas de pagamento e um objeto para calcular o valor final a ser cobrado, ele se parece com isso:

Gostou deste artigo?

Receba atualizações semanais com novos artigos do WebDevBr e outras dicas!

class Payment
{
    public function finalPrice(Products $products, string $methodOfPayment): float
    {
        $total = $products->getTotal();
        if ($methodOfPayment == 'boleto') {
            $price = $total + 1.50;
        } else if ($methodOfPayment == 'debito') {
            $price = $total * 1.05;
        } else if ($methodOfPayment == 'credito') {
            $price = $total;
        } else {
            throw new \Exception('Method is invalid');
        }
        return $price;
    }
}

Eu não sei vocês, mas toda vez que eu vejo a palavra else eu fico apavorado, isso pra mim quer dizer que minha classe (ou estrutura de classes) pode ser melhorada, depois que eu comecei a estudar clean code meu código mudou muito.

Agora imagine que você vai aceitar pagamento via PayPal, muito simples, mais um else if e ta resolvido? Mas se você se preocupa com seu código tanto quanto eu já deve saber que estamos quebrando o princípio "aberto para expanção, fechado para alteração" (ou Open/Closed principle) o O do SOLID, isso quer dizer que não podemos alterar um objeto para incluir um recurso novo nele, não é produtivo. Adivinhem qual é a solução?

Uma das possíveis soluções seria usar o Template Method que eu já comentei aqui no WebDevBr, mas desta vez eu vou preferir o Strategy, para este caso ele é mais simples e eficaz.

O padrão Strategy precisa de 3 coisas para existir, uma classe cliente, uma interface e classes concretas, vejamos um exemplo:

interface MethodOfPayment
{
    public function calc(float $total): float;
}

class Boleto implements MethodOfPayment
{
    public function calc(float $total): float
    {
        return $total + 1.50;
    }
}

class Debito implements MethodOfPayment
{
    public function calc(float $total): float
    {
        return $total * 1.05;
    }
}

class Credito implements MethodOfPayment
{
    public function calc(float $total): float
    {
        return $price = $total;
    }
}

Aqui temos então uma interface e 3 classes concretas que a implementa, vamos voltar a classe cliente, no nosso exemplo a Payment.

class Payment
{
    public function finalPrice(Products $products, MethodOfPayment $methodOfPayment): float
    {
        $total = $products->getTotal();
        return $methodOfPayment->calc($total);
    }
}

Ficou até mais interessante, o $methodOfPayment que antes recebia uma string passou a receber a nossa interface, ou seja, qualquer classe que use e siga as regras impostas pela MethodOfPayment, assim eu tenho certeza que tal objeto terá o método calc(), qual o tipo de variável ele aceita como entrada e qual a saída (recurso do PHP 7), afinal de contas a interface força isso.

Pra muita gente isso não faz sentido algum, afinal você acabou escrevendo muito mais do que antes, mas com certeza você não terá só uma classe/método cliente para calcular o preço final, ainda tem parcelas, descontos, cambio, fechamento do pedido, relatórios, administração, tem certeza que você não precisa se organizar? A maioria das pessoas só se da conta destes erros depois que já é tarde de mais.

Na prática, chamamos isso de programar para uma interface, o revéz (o primeiro exemplo com if e else) seria programar para uma implementação, o que não faz muito sentido na orientação a objetos.

Espero que este artigo tenha sido útil, e até a próxima pessoal!


Cursos relacionados


* Parcelamento apenas cartão de crédito! Pode haver uma pequena variação no parcelamento em relação a simulações apresentadas!