Refatorando código PHP para Strategy Pattern \| TreinaWeb               Promoção no ar   Matricule-se agora e garanta **54% de desconto**  

  Termina em   Tempo restante da oferta: 13 Horas 

 10 Min 

 23 Seg 

   Tempo restante da oferta: 13 10 23 

  [Assinar →](https://www.treinaweb.com.br/checkout/pagamento/plano/anual?cupom=TW-SCLIENTE26) 

   [                ](https://www.treinaweb.com.br)  Explorar  

 [ Quanto custa? ](#assinatura) [ FAQ ](https://www.treinaweb.com.br#faq) [Matricule-se](#assinatura) [ Entrar ](https://www.treinaweb.com.br/login) 

     [ Início ](https://www.treinaweb.com.br) [ Artigos ](https://www.treinaweb.com.br/blog) Refatorando código PHP para Strategy Pattern  [ PHP ](https://www.treinaweb.com.br/blog/categoria/php) [ Padrões de Projeto ](https://www.treinaweb.com.br/blog/categoria/padroes-de-projeto) 

# Refatorando código PHP para Strategy Pattern

 Veremos nesse artigo o padrão de projeto Strategy em PHP, aplicaremos refatoração para implementá-lo na resolução um determinado problema.

 [ Redação Treinaweb ](https://www.treinaweb.com.br/blog/autor/redacao-treinaweb) 10 anos atrás

  ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2017/07/refatorando-codigo-php-para-strategy-pattern.jpg)  

Quando falamos de Design Patterns, fica muito nebuloso entender o que podemos fazer com eles, pois o que muitos desenvolvedores não compreendem é que os padrões resolvem problemas de código ou de design já identificados ou simplesmente melhoram a manutenibilidade do projeto. Para que isso aconteça primeiro precisamos passar pelo problema, conhecer o que o padrão resolve e enfim aplicar uma refatoração.

Vamos falar neste artigo sobre o **Strategy**, que é um padrão comportamental, muito usado para quando temos regras de uma determinada atividade que podem conter muita lógica, ele organiza e separa o uso dessas lógicas, padronizando a usabilidade das classes de forma que novas implementações possam ser adicionadas no futuro sem muita mudança no uso de uma determinada classe de ação.

Para ilustrá-lo usaremos a refatoração, veremos o problema e aplicaremos o padrão resolvendo uma problemática específica. Para que fique menos complexo tudo será demonstrado em código e comentários, assim acredito que chegaremos a um entendimento melhor.

[  ![Symfony - Template Engine Twig](https://d2knvm16wkt3ia.cloudfront.net/assets/svg-icon/twig.svg)   Curso Symfony - Template Engine Twig Conhecer o curso ](https://www.treinaweb.com.br/curso/symfony-template-engine-twig)

## Problemática

Temos um sistema de gestão de logística e precisamos comunicar aos cliente quando o produto chegou na distribuidora, quando está a caminho da entrega e por fim o momento em que ele foi recebido pelo cliente.

Para tratar das mensagens que são enviadas aos clientes, foi criada uma classe **Message** da qual comunica por e-mail os clientes, veja abaixo a representação:

```php
class Message
{
    // ...
    public function send(string $message)
    {
        // implementação de mensagem por email
    }
}

// ...
$message->send('Seu produto está a caminho da entrega');

```

Com o evoluir da aplicação foi preciso implementar um novo modelo de mensagem, o SMS, pois alguns clientes não possuíam cadastro online, e o sistema só possui cadastro simples como: o nome, telefone e endereço.

Resolvemos então criar duas classes, seguindo o principio de SOLID, [single responsibility](https://en.wikipedia.org/wiki/Single_responsibility_principle), a classe *EmailMessage* e a *SMSMessage*, pensando em futuras implementações fizemos a classe *MessageManager* retornar o objeto de acordo com o tipo de mensagem necessária.

```php
class MessageManager
{
    // ...
    public function getSender()
    {
        if ($this->customer->fromOnline() && $this->customer->hasEmail()) {
            return new EmailMessage;
        }
        if ($this->customer->hasEmail() === false) {
            return new SMSMessage;
        }
        // ...
    }
}

// ...
$sender = $messageManager->getSender();
$sender->send('Seu produto está a caminho da entrega');

```

Mas como nada é perfeito, uma nova forma de comunicação entrou no projeto, os desenvolvedores precisam agora de um novo modo de envio, este agora via *push notification*, ou seja, a notificação será via aplicativo de celular, da forma atual nos forçou a ter essa implementação:

```php
class MessageManager
{
    // ...
    public function getSender()
    {
        if ($this->customer->fromOnline() && $this->customer->hasEmail()) {
            return new EmailMessage;
        }
        if ($this->customer->hasEmail() === false) {
            return new SMSMessage;
        }
        if ($this->customer->hasCellPhone()) {
            return new PushMessage;
        }
        // ...
    }
}

// ...

```

[  ![Yii - Framework PHP](https://d2knvm16wkt3ia.cloudfront.net/assets/svg-icon/yii-framework.svg)   Curso Yii - Framework PHP Conhecer o curso ](https://www.treinaweb.com.br/curso/yii-framework-completo)

## Uma solução

Claramente não estamos seguindo corretamente a responsabilidade única, a classe *MessageManager* está com muitas regras de mensagem que se mesclam entre si, observamos que as regras de cada classe de mensagem deve estar dentro delas mesmas e o manager só deve invocar o objeto pedido no momento, pois ainda que surjam novas formas de mensagens, seria muito doloroso dar manutenção e testar esse método *getSender()*.

Com o **Strategy** transformamos cada regra em sua classe, que deve ser passada pelo desenvolvedor, elas seguirão uma interface:

```php
interface MessageSenderInterface
{
    // ...
    public function send(string $message) : bool;
    public function isValidSender() : bool;
}

// ...

```

Essa interface fará o contrato das estratégias para que todas sigam esses métodos, implementaremos uma das classes de mensagens adicionando Strategy no nome original:

```php
class EmailMessageStrategy implements MessageSenderInterface
{
    // ...
    public function send(string $message) : bool
    {
        // Valida de acordo com a regra deste tipo de mensagem
        if ($this->isValidSender()) {
            return $this->sendMessage($message);
        }
        return false;
    }

    public function isValidSender() : bool
    {
        if ($this->customer->fromOnline() && $this->customer->hasEmail()) {
            return true;
        }
        return false;
    }
}
// ...

```

Isso deve ser feito também para as demais classes de mensagem, essa prática isola as regras/validações nas classes *Strategy* de mensagens. Agora faremos o *MessageStrategy*, que invocará o método da classe em que lhe for informado. Abaixo a implementação do padrão:

```php
class MessageStrategy implements MessageSenderInterface
{
    // ...
    public function __construct(MessageSenderInterface $sender)
    {
        // Guardamos o objeto Message com suas regras e implementações
        $this->sender = $sender;
    }

    public function send(string $message) : bool
    {
        // Retorna a validação de acordo com a regra do objeto
        return $this->sender->send($message);
    }

    public function isValidSender() : bool
    {
        return $this->sender->isValidSender();
    }
}

// ...
// Ao criar o objeto MessageStrategy devemos informar qual o tipo de envio
$message = new MessageStrategy(new EmailMessageStrategy);

// O método invoca o send original da classes anteriormente adicionada
$message->send('Seu produto está a caminho da entrega');

```

Pronto! Agora a implementação é injetada no *MessageStrategy* podendo haver outras implementações sem precisar alterar a classe *MessageStrategy* e, o melhor: as regras específicas para cada modelo de mensagem estarão em suas respectivas classes.

## Conclusão

A vantagem em usar esse padrão está em facilitar a organização das classes, centralizar a usabilidade e além disso também dar poder ao desenvolvedor de adicionar camadas na estratégia principal que será replicada a todas as outras estratégias que são injetadas.

Espero que tenham gostado do artigo, a ideia foi ilustrar uma forma de implementar o padrão **Strategy** de forma simples, lembrando que existem várias maneiras de implementá-lo e os exemplos apresentados acima são meramente uma prova de conceitos.

Até a próxima!

[  ![PHP Avançado](https://d2knvm16wkt3ia.cloudfront.net/assets/svg-icon/php.svg)   Curso PHP Avançado Conhecer o curso ](https://www.treinaweb.com.br/curso/php-avancado)

- [ #PHP ](https://www.treinaweb.com.br/blog/tag/php)
- [ #Design Pattern ](https://www.treinaweb.com.br/blog/tag/design-pattern)

Autor

 ![Redação Treinaweb](//secure.gravatar.com/avatar/662942287935c97e547cfc12c04be6e5?d=mm)

## Redação Treinaweb

 [Todos os artigos](https://www.treinaweb.com.br/blog/autor/redacao-treinaweb)  

## Continue estudando

 Transforme leitura em prática com os cursos e formações da TreinaWeb.

 [Ver cursos](https://www.treinaweb.com.br/cursos)   

  Continue lendo

## Artigos relacionados

- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2020/03/iterators-php-400x280.png)  [ PHP ](https://www.treinaweb.com.br/blog/categoria/php) 

     7 anos atrás

    ##  [ Generators no PHP ](https://www.treinaweb.com.br/blog/generators-no-php) 

     Saiba o que são Iterators e Generators, bem como os seus casos de uso.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2021/05/background-post-400x280.jpg)  [ Algoritmos ](https://www.treinaweb.com.br/blog/categoria/algoritmos) 

     10 anos atrás

    ##  [ Complexidade ciclomática, análise estática e refatoração ](https://www.treinaweb.com.br/blog/complexidade-ciclomatica-analise-estatica-e-refatoracao) 

     Veremos nesse artigo como se dá a mensuração da complexidade ciclomática; como os analisadores estáticos podem nos auxiliar e a importância da refatoração.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2020/03/05155042/iterators-php-400x280.png)  [ PHP ](https://www.treinaweb.com.br/blog/categoria/php) 

     7 anos atrás

    ##  [ Iterators no PHP ](https://www.treinaweb.com.br/blog/iterators-no-php) 

     Iterator é um mecanismo que permite que um objeto seja iterado e ele próprio fica no controle granular dessa iteração.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2022/08/COMO-SE-PREPARAR-PARA-ENTREVISTA-TECNICA-400x280.png)  [ Carreira ](https://www.treinaweb.com.br/blog/categoria/carreira) 

     4 anos atrás

    ##  [ Como se preparar para entrevistas técnicas ](https://www.treinaweb.com.br/blog/como-se-preparar-para-entrevistas-tecnicas) 

     Geralmente, quando participamos de um processo seletivo para uma vaga relacionada a desenvolvimento, há uma etapa técnica, onde os entrevistadores irão avaliar suas competências técnicas, sua linha de raciocínio lógico e a maneira como você emprega ferramentas e tecnologias para a resolução de problemas. Neste artigo, separamos algumas dicas para que você possa se sair bem nesta etapa.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2018/08/27124433/lambda-400x280.png)  [ PHP ](https://www.treinaweb.com.br/blog/categoria/php) 

     8 anos atrás

    ##  [ Closures e funções anônimas no PHP ](https://www.treinaweb.com.br/blog/closures-e-funcoes-anonimas-no-php) 

     Conheça mais sobre as funções anônimas, como se comportam no PHP e em qual momento se tornam closures. Além disso, entenda como funcionam os métodos bind(), call() e bindTo() da classe especial Closure.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2021/05/87asgh12-400x280.png)  [ Orientação a Objetos ](https://www.treinaweb.com.br/blog/categoria/orientacao-a-objetos) 

     10 anos atrás

    ##  [ Devo usar herança ou composição? ](https://www.treinaweb.com.br/blog/devo-usar-heranca-ou-composicao) 

     A composição permite um reuso e extensão de código mais flexível que a herança clássica. Mas isso é motivo para sempre a escolhermos em detrimento à herança clássica?

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2020/04/24104644/O-QUE-É-IDE-400x280.png)  [ Tecnologia ](https://www.treinaweb.com.br/blog/categoria/tecnologia) 

     7 anos atrás

    ##  [ O que é uma IDE (Ambiente de Desenvolvimento Integrado)? ](https://www.treinaweb.com.br/blog/o-que-e-uma-ide-ambiente-de-desenvolvimento-integrado) 

     Veja neste artigo o que é uma IDE e suas principais características.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2022/10/o-que-e-e-como-comecar-com-golang-400x280.jpg)  [ Desenvolvimento Back-end ](https://www.treinaweb.com.br/blog/categoria/desenvolvimento-back-end) 

     4 anos atrás

    ##  [ Estruturas condicionais e de repetição na Go ](https://www.treinaweb.com.br/blog/estruturas-condicionais-e-de-repeticao-na-go) 

     Veremos nesse artigo sobre quais são e como podemos utilizar as estruturas condicionais e as estruturas de repetição na linguagem Go

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2022/05/como-instalar-o-csharp-e-nosso-primeiro-exemplo-400x280.png)  [ C# ](https://www.treinaweb.com.br/blog/categoria/csharp) 

     4 anos atrás

    ##  [ Estruturas condicionais e de repetição no C# ](https://www.treinaweb.com.br/blog/estruturas-condicionais-e-de-repeticao-no-csharp) 

     Veremos nesse artigo sobre quais são e como podemos utilizar as estruturas condicionais e as estruturas de repetição no C#

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2019/07/23215528/capa-boas-praticas-400x280.png)  [ Desenvolvimento ](https://www.treinaweb.com.br/blog/categoria/desenvolvimento) 

     7 anos atrás

    ##  [ Boas práticas de programação para iniciantes ](https://www.treinaweb.com.br/blog/boas-praticas-de-programacao-para-iniciantes) 

     Veja neste artigo algumas boas práticas que você deve adotar enquanto escreve seu código.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2019/02/01143234/PROVEDORES-LOG-400x280.png)  [ Desenvolvimento Back-end ](https://www.treinaweb.com.br/blog/categoria/desenvolvimento-back-end) 

     7 anos atrás

    ##  [ Switch Expressions no C# 8.0 ](https://www.treinaweb.com.br/blog/switch-expressions-no-c-8-0) 

     Obtenha uma visão geral do recurso switch expressions do C# 8.0 e aprenda a criar códigos mais limpos e legíveis nesta versão da linguagem.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2021/03/principais-ides-para-desenvolvimento-dart-400x280.png)  [ Dart ](https://www.treinaweb.com.br/blog/categoria/dart) 

     6 anos atrás

    ##  [ Principais IDEs para desenvolvimento Dart ](https://www.treinaweb.com.br/blog/principais-ides-para-desenvolvimento-dart) 

     Veja neste artigo as principais IDEs para desenvolvimento Dart.

     Ler artigo

## Um ano de acesso total para você viver de programação.

 Todos os cursos e formações da TreinaWeb numa única assinatura, com professores que atuam no mercado, suporte direto e certificados. Do primeiro `console.log` ao mercado de trabalho.

- **1 ano** de acesso a **todos os cursos**
- Cursos novos **toda semana**
- Suporte **direto com professores**
- Plano de carreira **personalizado**
- **Certificados digitais** inclusos
- **Aplicativos** para Android e iOS, com **acesso offline**

    **Garantia incondicional de satisfação** 

 Teste por 7 dias e, se não fizer sentido para você, devolvemos seu dinheiro.

### Acesso completo a todos os cursos e dezenas de Formações.

 12 meses 

  Economize R$ 840,00  54% OFF 

 de 12x R$ 129,00 por apenas

 12x  R$ 59,00

 sem juros no cartão de crédito ou R$ 599,00 à vista

  Oferta termina em  **13h 10min 23s**

- Acesso imediato e ilimitado durante 1 ano.
- Plano de carreira personalizado.
- Suporte direto com professores.
- E muito mais!

 [Matricule-se agora](https://www.treinaweb.com.br/checkout/pagamento/plano/anual?cupom=TW-SCLIENTE26)

     [                ](https://www.treinaweb.com.br)

 Escola online de programação, tecnologia e IA.

- [  ](https://www.facebook.com/TreinaWeb/)
- [  ](https://www.instagram.com/treinaweb/)
- [  ](https://www.youtube.com/user/TreinaWeb)
- [  ](https://twitter.com/treinaweb)
- [  ](https://www.linkedin.com/company/treinaweb)
- [  ](https://github.com/treinaweb)

## Inscreva-se em nossa newsletter

Receba lançamentos, promoções e novidades.

   Seu nome     Seu WhatsApp     Seu melhor e-mail   Inscrever-se 

## Cursos

- [ Base para Devs ](https://www.treinaweb.com.br/categoria/base-para-devs)
- [ Front-end ](https://www.treinaweb.com.br/categoria/desenvolvimento-front-end)
- [ Back-end ](https://www.treinaweb.com.br/categoria/desenvolvimento-back-end)
- [ Mobile ](https://www.treinaweb.com.br/categoria/desenvolvimento-mobile)
- [ Bancos de Dados ](https://www.treinaweb.com.br/categoria/bancos-de-dados)
- [ Cloud ](https://www.treinaweb.com.br/categoria/cloud-computing)
- [ IA ](https://www.treinaweb.com.br/categoria/ia)
- [ E mais ](https://www.treinaweb.com.br/categoria/e-mais)
- [ Ver todos os cursos ](https://www.treinaweb.com.br/cursos)

## Conteúdo

- [ Formações ](https://www.treinaweb.com.br/formacoes)
- [ Projetos práticos ](https://www.treinaweb.com.br/projetos-praticos)
- [ Direto ao ponto ](https://www.treinaweb.com.br/direto-ao-ponto)
- [ Planos ](https://www.treinaweb.com.br#assinatura)
- [ Depoimentos ](https://www.treinaweb.com.br#depoimentos)
- [ Comunidade ](https://www.treinaweb.com.br#comunidade)
- [ Corpo docente ](https://www.treinaweb.com.br#docente)

## A empresa

- [ Sobre a TreinaWeb ](https://www.treinaweb.com.br#sobre)
- [ Perguntas frequentes ](https://www.treinaweb.com.br#faq)
- [ Vantagens de estudar na TreinaWeb ](https://www.treinaweb.com.br/vantagens-de-estudar-na-treinaweb)
- [ Cursos para empresas ](https://www.treinaweb.com.br/empresas)
- [ Sugira um novo curso ](https://www.treinaweb.com.br/sugerir-curso)
- [ Trabalhe conosco ](https://www.treinaweb.com.br/trabalhe-conosco)
- [ Artigos ](https://www.treinaweb.com.br/blog)
- [ Desenvolvedores e agentes ](https://www.treinaweb.com.br/developers)
- [ Contato ](https://www.treinaweb.com.br/contato)
- [ Política de privacidade ](https://www.treinaweb.com.br/politica-de-privacidade)
- [ Termos de uso ](https://www.treinaweb.com.br/termos-de-uso)

## Baixe nosso aplicativo

 [   Disponível na **App Store**  ](https://apps.apple.com/us/app/treinaweb/id1322729447) [   Disponível no **Google Play**  ](https://play.google.com/store/apps/details?id=br.com.treinaweb.mobile) 

  Av. Paulista, 1765, Conj 71 e 72 · Bela Vista · São Paulo · SP · 01311-200   © 2004 – 2026 TreinaWeb Tecnologia LTDA · CNPJ 06.156.637/0001-58
