Substituindo If´s por uma implementação no padrão Strategy com C#

Marcio Nizzola
4 min readNov 10, 2022

--

Muitas vezes temos inúmeras situações principalmente quando trabalhamos com sistemas legados, onde nos deparamos com aquelas estruturas com if´s intermináveis ou switch cheios de regras de negócio.

Vou exemplificar aqui uma situação básica, que todo desenvolvedor já se deparou, mas neste caso só está sendo feito um cálculo, mas temos vários casos bem extensos.

No caso acima, trata-se de uma classe responsável pela conversão de moedas, e a cada vez que resolvemos colocar uma nova moeda, temos que ir até o IF e modificar, neste caso, ainda está bonito, mas temos situações como por exemplo, cálculo de impostos, cálculo de preços de venda, entre outras coisas, que não se trata de uma simples operação de multiplicação ou divisão, e sim cálculos complexos.

Sendo assim, além do código começar a ficar muito grande, fica mais difícil alterar alguma coisa, sem que possa causar impacto em todos os cálculos em caso de alteração, o risco fica maior.

Prezando pela responsabilidade única da classe e também pela organização, podemos implementar o padrão de projeto chamado Strategy, que permite-nos utilizar interfaces e classes separadas para tratar cada caso.

Vamos então criar uma interface:

E para cada moeda específica, criaremos a nossa classe, colocando as regras de cada uma separadamente, permitindo implementar testes de unidade, e também garantindo que a alteração de uma classe, não afete as demais regras.

Fazemos então uma classe para conversão de EURO.

Uma para conversão de dólar.

E assim por diante, vamos criar uma classe para cada moeda.

E depois criaremos uma classe única que receberá os conversores como parâmetro, assim podemos criar quantos conversores quisermos para quantas moedas forem necessárias, sem alterar lógicas com “if´s”:

Isto permite garantir a testabilidade de cada classe, isoladamente, e também facilita para encontrarmos onde se encontram as regras de cada caso, não precisando correr por if´s intermináveis, e acaba também com aquela história de “conserta um, quebra outro” !

Para testar a aplicação disso, vemos abaixo o código como fica:

Desta forma, passamos a classe específica para cada situação não requerendo que if´s intermináveis aconteçam mais.

E como fazer os testes?

Bom, já que é pra testar, podemos fazer de diversas formas, mas como todo programador não gosta de escrever muito…. vamos fazer um teste de exemplo somente indicando as classes que queremos testar, dentro do parâmetro “InlineData”.

Assim, dentro do teste, instanciaremos a classe, e poderemos utilizar o mesmo teste para todas elas.

Faremos a conversão de um valor base, que no exemplo coloquei “10” e assim, converteremos utilizando as duas funções, e ao final comparamos para ver se o valor volta a ser igual ao original.

É um teste bobo, mas só um exemplo de tudo que podemos fazer ao utilizar este padrão, poderíamos em outras situações, fazer os testes passando também parâmetros de valor a serem obtidos em cada cálculo.

Mas a idéia principal, é escrever poucos testes passando somente os tipos de objeto.

ah, mas como é que funcionou este “GetInstance”? tá bom, existe uma função que tava perdida por aí na Web, que permite que eu instancie uma classe através do nome do seu tipo.

Vou colar ela abaixo para quem quiser utilizar também!

No primeiro trecho de código, ele simplesmente procura no assembly que estamos pela classe (1).

Caso não ache, faz um foreach percorrendo todos os assemblies vinculados ao projeto para que encontre a respectiva classe. (2).

CONSIDERAÇÕES FINAIS:

Esta semana mesmo, utilizamos para algumas regras de negócio para preços e margens de lucro no trabalho, e mudou bem a forma como o código ficou legível, pois cada cálculo tinha várias linhas e variações.

Com isso podemos reduzir a incidência daquelas famigeradas linhas de código feitas sob a metodologia “Extreme Go-Horse”.

Gostou do artigo? clique no ícone👏e também me siga para ver as próximas publicações !!

Referências:

Repositório do projeto: https://github.com/NIZZOLA/StrategyPatternSample

--

--

Marcio Nizzola
Marcio Nizzola

Written by Marcio Nizzola

Microsoft MVP | Software Architect na CI&T | Prof. da Etec Itu | Membro Fundador da Comunidade Itu Developers.

No responses yet