Descomplicando o Strategy

02 08 2021

Se você está iniciando no mundo de padrões de projeto e qualidade de código e ainda não ouviu falar sobre o Strategy, não se preocupe! No decorrer deste artigo, eu vou tentar descomplicá-lo e convencer você a utilizá-lo com mais frequência em sua rotina.

1. Padrões de projeto

“Afinal, o que são padrões de projeto?”

Como a GoF (Gangue dos Quatros) descreve em seu livro Padrões de Projeto, “[…] um padrão de projeto nomeia, abstrai e identifica os aspectos-chave de uma estrutura de projeto comum para torná-la útil para a criação de um projeto orientado a objetos reutilizável […]”.

“E o que isso significa?”

É bem mais simples do que parece, viu? Padrões de projeto, como o nome sugere, são padrões que podem ser reutilizados em outros sistemas, pois trata-se de uma abstração de uma ideia, um padrão que foi identificado dentro do código. Também é amplamente conhecido por ser, simplesmente, uma forma de catalogar soluções a problemas comuns.

Se este é o seu primeiro contato com padrões de projeto, a ideia pode parecer um tanto abstrata, mas vamos seguir com a prática para tentar facilitar o entendimento.

Especificamente sobre o padrão de projetos Strategy:

Este padrão visa facilitar a manutenibilidade e tornar a potencial expansão do seu código mais simples e objetiva. Isso é possível através da descentralização da responsabilidade da manipulação de um objeto abstraído por uma interface e suas diferentes “estratégias” de implementações.

2. O Strategy na prática

Saindo um pouco da teoria e indo para a prática, vamos visualizar um problema, refletir sobre ele e, então, partir direto para uma abordarem de implementação do Strategy.

2.1. O Problema

Imagine que exista um objeto Funcionario com suas propriedades e uma classe CalculadoraSalarial que realiza o reajuste salarial deste funcionário de acordo com sua performance durante o ano. A performance do funcionário é medida por um ENUM que existe dentro das propriedades do mesmo.

Agora, imagine as seguintes regras de negócio:

  • Se o funcionário tiver uma performance NEGATIVA no momento do cálculo, ele não deve receber reajuste salarial.
  • Se o funcionário tiver uma performance POSITIVA no momento do cálculo, seu salário deve receber um reajuste de 5%.

Devido a lógica por trás do negócio, não faz sentido retornar um valor de reajuste “x” por padrão. Assim, também criamos uma exceção caso no futuro exista algum novo tipo de performance que esquecemos de implementar na nossa calculadora.

Implementando o método reajustaSalario (no exemplo, utilizando Java), iremos chegar a um resultado parecido com o seguinte:

O código está funcional. Entretanto, uma semana após a implementação, suponhamos que foi solicitada a criação de um novo tipo de performance: EXCELENTE. O funcionário que possuir a performance “excelente” recebe 10% de reajuste salarial.

Sendo simples e direto, o ENUM seria implementado com mais um tipo, o “EXCELENTE”. Por último, a implementação do método reajustaSalario ficaria algo como:

Em cenários como este ─, mas não limitado à, onde o código pode facilmente se expandir criando uma corrente de IFs, o padrão Strategy pode ser aplicado. No exemplo acima, estamos “pegando leve” ─ no mundo real, é muito mais comum encontrar IFs encadeados, muitas vezes em situações piores do que o nosso. Tudo isso prejudica legibilidade do código como um todo e, no geral, não é uma boa prática.

2.2. A solução

“Certo. E como podemos aplicar o Strategy nesse caso?”

Antes mesmo de responder, já adianto: não existe uma única forma de resolver esse tipo de problema.

Existem diversas formas de se resolver um problema com Strategy, a maioria delas envolvendo a implementação de uma interface ou de uma abstração. No nosso caso, as coisas são bem mais simples graças ao nosso ENUM.

Provavelmente, até agora, a nossa implementação de Performance foi a seguinte:

Através de abstração, como já mencionado, facilmente podemos resolver o nosso problema neste caso. Ao implementarmos um método abstrato dentro do nosso ENUM, todos os diferentes tipos dentro dele exigirão uma implementação, causando erro em tempo de compilação caso essa exigência não seja atendida, obrigando o desenvolvedor a implementar o método.

E, assim, podemos alterar a forma que a nossa calculadora retorna o reajuste salarial do funcionário, facilitando imensamente a leitura do código, tornando mais simples a manutenção do mesmo e, é claro, seguindo os princípios SOLID. Basicamente, contanto que a regra de negócio fundamental não mude, não precisamos mais sequer tocar na nossa “Calculadora”.

Como temos certeza de que o método retornaReajusteSalarial possui sua devida implementação dependendo do tipo de performance, garantimos, também, que não exista o cenário descrito anteriormente, onde o desenvolvedor esqueceu de implementar o cálculo do reajuste.

Um lembrete: Essa não é a única forma de implementar o padrão de projeto Strategy, mas é um jeito bem bacana de exemplificar como é bem mais fácil de implementá-lo no nosso código do que geralmente é pensado. 

3. Opinião do Autor

O padrão de projetos Strategy, por mais que seja diversas vezes confundido por parecer complexo, é bem mais simples de ser implementado do que parece e poderia muito bem ser mais visto no código de vários sistemas orientados a objeto.

Durante o desenvolvimento, às vezes podemos erroneamente assumir que tentar aplicar Design Patterns consome muito tempo. Isso está errado. Design Patterns, uma vez conhecidos e dominados, eles só têm a agregar para a velocidade e elegância da sua solução. Padrões de projeto facilitam o desenvolvimento e tornam a manutenibilidade e evolução do código mais simples.

Postagens relacionadas

Se você aceitar vamos utilizar cookies para melhorar sua experiência neste site. Alguns coletarão suas preferências de uso (idioma, localização, personalização), outros coletarão estatísticas. Você pode aceitar ou declinar, mas em todos os casos a Softplan encoraja você a ler o nosso Aviso de Privacidade.