Artigo

    

Refatoração utilizando Strategy com PHP

Orientação a objetos e design patterns, são os principais assuntos abordados neste artigo, através de um estudo de caso sobre como foram aplicadas as técnicas, mostrando que, de fato, o PHP oferece um excelente suporte a orientação a objetos.


Por Eduardo Cesar Borsato de Oliveira



Neste artigo, vamos descrever um caso de uso e uma implementação do padrão Strategy em PHP, com o intuito de demonstrar como a linguagem tem avançado e melhorado nos últimos tempos, em detrimento de épocas onde era tido como "fraco" ou "incompleto".


Atualmente, o PHP possui um excelente suporte á orientação a objetos, algo que há tempos atrás  fazia muitos programadores sentirem certo “receio” quando iniciavam-se debates sobre o assunto relacionado à PHP.


Um problema, uma solução


Em um sistema desenvolvido para um laboratório de estatística  foi solicitado o seguinte requisito:
-  É necessário que o sistema efetue o cálculo de médias com base nos valores informados pelos pesquisadores;
-  Inicialmente existirão 2 cálculos para média:
   1 – Cálculo da média aritmética, a qual o pesquisador deverá informar os valores e o sistema por sua vez efetuará o cálculo devolvendo a média obtida.
   2 – Cálculo da média ponderada, onde o pesquisador deverá sempre informar a nota seguida de seu respectivo peso, e o sistema procederá efetuando o cálculo e retornando a média obtida.



A solução atual


O desenvolvedor responsável pela criação de tal requisito sugeriu a criação de uma classe que receberia os parâmetros necessário e, realizaria os cálculos através de seus métodos para cálculos de média.


Figura 1 Classe que propõe a solução atual


Estudo da solução atual


O código da classe resolve o problema. A classe possui atributos internos utilizados para fazer o cálculo, métodos que adicionam e utilizam dados para o cálculo e dois métodos cada um com seu algoritmo de média respectivo. Contudo, essa classe viola alguns princípios SOLID tais como o da responsabilidade única onde uma classe deve ter um (e apenas um) motivo para mudar, e o fato de que temos os dois métodos de cálculos de média e os métodos que adicionam e recuperam os dados para os dois casos de média, fazem com que a classe viole este princípio. Outro princípio SOLID também é violoado: o princípio de entidades abertas e fechadas (entidades de software (classes, módulos, funções etc.) devem ser abertas para extensão mas fechadas para modificação), por exemplo, caso tenha a necessidade de inserir um novo cálculo de média com novos métodos para adicionar e recuperar valores específicos a essa nova rotina de cálculo, seriam motivos necessários para uma alteração na classe Média(Average) em um código já existente e funcional, que não deveria sofrer mais alterações após colocado em produção, mexer em uma parte de código que já está  funcionando aumenta os riscos de quebra do aplicativo.



Refletir sobre tais pontos torna-se importante, afinal, não é desejado que, após implementar um novo requisito, os requisitos antigos deixem de funcionar por alguma falha de programação que possa ter ocorrido no código em funcionamento, enquanto era implementado um novo requisito. Logo, é necessário preocupar-se com o design do código escrito e com a forma como ele pode escalonar para atender novos requisitos sem influenciar os já existentes.



Uma solução que não viole os princípios


A partir do momento que as fraquezas surgem em um código, tenhamos em mente os seguintes pensamentos:





“É necessário separar o cálculo de média ponderada e seus parâmetros de entrada, do cálculo de média aritmética e seus parâmetros de entrada.”




“Cada algoritmo de cálculo de média possui uma implementação diferente.”





Notar a violação dos princípios SOLID resultou em tais pensamentos, que por sua vez facilitam as coisas, definindo de forma clara o que precisa ser feito para melhorar o código.



A solução cabível para este problema engloba um padrão de desenvolvimento (design pattern) chamado Strategy, que é um design pattern comportamental: define uma família de algoritmos e encapsula cada uma deles permitindo que sejam intercambiáveis.



Este padrão provê uma abstração do conceito que está envolvido no problema e uma separação das variadas formas de implementação que possa existir para o conceito em questão, isso torna o código que resolve o problema mais flexível, tornando possível realizar a modificação do comportamento sem o alterar código existente, apenas adicionando novas estratégias de  uso.
Para o melhoramento do código, o uso desse padrão faz sentido pois é preciso separar as responsabilidades, para que o princípio da responsabilidade única não seja violado. Enxergar o conceito envolvido no problema e toda variação que possa existir para ele é importante nesse caso para que não seja viole o princípio de entidades abertas e fechadas, ou seja, o novo código deve ser capaz de suportar novas implementações sem que seja preciso alterar o código já funcional, apenas adicionando novas estratégias. Segue um diagrama de classe do padrão aplicado à solução:


Figura 2 Strategy representando a solução do problema.

O conceito principal por trás do problema são as médias. Existe uma família de médias: as aritméticas, as ponderadas, geométricas etc. Logo, temos diversos tipos de cálculo para umadeterminada média, que no caso é utilizada duas formas: para o cálculo de média aritmética e para o cálculo de média ponderada. Através do diagrama também fica notável como é feita a separação das responsabilidades e o encapsulamento dos algoritmos de cálculos em suas respectivas classes. Fica evidente também como se torna fácil adicionar um  novo algoritmo de cálculo de média sem precisar alterar código existente e que já está funcionando.



Outro participante importante no padrão é o contexto, no caso, os valores(Values), esse participante pode configurar todos os parâmetros que serão utilizados pelas estratégias. No exemplo, Valores (Values) é o contexto. Sendo uma classe abstrata, a qual define um método de chamada para estratégia e métodos para que se adicione e recupere parâmetros que serão usados para os cálculos.



Sendo assim, a classe Valores é estendida para Ponderada (Pondered) e Aritmética (Arithmetic). O fato de tal comportamento ser necessário neste exemplo, é que o cálculo de médias ponderadas e aritméticas possuem parâmetros de entrada diferentes.



Enquanto para o cálculo de média aritmética só são esperados os valores em si, para o de média ponderada já são necessários, além dos valores, seus respectivos pesos. Logo, fazê-lo de tal forma permite que isso aconteça sem sobrecarregar as responsabilidades de uma classe, no exemplo inicial a classe Média recebe os parâmetros para os dois métodos de cálculos além de possuir também suas implementações.



Na forma refatorada isso não acontece, pois seguindo o padrão Strategy foi possível abstrair um conceito do problema, no caso os cálculos de média e, posteriormente identificando as variadas implementações de algoritmos que existiam foi possível seguir com a implementação do padrão. Possuindo uma interface Media(Average), que seria o participante estratégia (Strategy), a partir daí tornou-se possível delegar a implementação de seu método de cálculo para cada classe que derivar dessa interface. As classes que derivam dessa interface são conhecidas como estratégias concretas (Concrete Strategy). Assim sendo, cada classe que implementar a interface Média deve implementar o seu método de cálculo da maneira que for necessário. O interessante é que, é possível ter agora, de forma separada e organizada, as mais variadas implementações de cálculo de média existente. A responsabilidade em lidar com os parâmetros necessários para cada estratégia de cálculo de média ficou por conta do contexto, como cada tipo de cálculo de média requer parâmetros de entrada diferentes, ter classes que saibam como fazê-lo para cada caso torna-se necessário.



Ao observar o código inicial, e refletir sobre o que alguns princípios SOLID propõe, tornou-se possível identificar os principais pontos de melhorias que, para serem colocados em prática, fizeram o uso de um padrão que permitiu à nova implementação, a não violação dos princípios adicionando mais flexibilidade e organização ao código.


 


Eduardo Cesar Borsato de Oliveira, é analista e desenvolvedor. Trabalha com criação de softwares para Internet utilizando PHP como linguagem principal. Estudou diversas áreas da engenharia de software com ênfase mais especificamente sobre construção de softwares de alta qualidade, boas práticas de programação e refatoração.
Contato com o autor: Linkedin

Notícias

Soluti Certificação Digital em busca de especialista Linux

Publicado em: 19/04/2017 às 17:18 | leituras |

A Soluti Certificação Digital está em busca de um profissional para atuar como especialista Linux em Goiânia.

Vaga para analista de TI com experiência em ECM/GED, BPM e BI

Publicado em: 16/12/2016 às 11:12 | leituras |

Renomada empresa de serviços de consultoria em TI, está em busca de um analista de TI para trabalhar em projetos de implementação de soluções ECM/GED, BPM e BI usando os sistemas Alfresco, Activiti, Bonita, Camunda e SpagoBI.

Nova versão do Scalix Groupware oferece suporte completo a IBM Power & IBM Mainframes

Publicado em: 14/12/2016 às 12:59 | leituras |

A nova versão dá liberdade de escolha às empresas para usar as tecnologias mais modernas oferecidas pelo mercado como base para sua solução de e-mail e colaboração

Software Livre e de Código Aberto: uma questão de economia, não de política

Publicado em: 12/11/2016 às 12:36 | leituras |

Os argumentos apresentados neste artigo são todos aspectos econômicos, e não aspectos políticos. Decisões baseadas em política (e não em economia) devem ser lembradas pelos eleitores nas próximas eleições.

Lançamento: E-book E-mail e Colaboração no Século XXI (grátis)

Publicado em: 29/09/2016 às 9:15 | leituras |

A Linux Magazine, em parceria com a Scalix Brasil e a Linux Solutions, acaba de lançar o novo ebook da série "Technology Report": E-mail e Colaboração no Século XXI. Baixe gratuitamente!


Mais notícias

lançamento!

LM 119 | Backup e Restauração




Impressa esgotada
Comprar Digital  R$ 10,90 Digital

  1. Baixe o curso de shell script do Julio Cezar Neves

    Publicado em 07/04/2008 às 19:41 | 408116 leituras

  1. Resultado do concurso "Por que eu mereço ganhar um netbook?"

    Publicado em 30/09/2009 às 3:00 | 177427 leituras

  1. Software público brasileiro na Linux Magazine Especial

    Publicado em 29/07/2011 às 15:07 | 156891 leituras

  1. Lançado o phpBB 3

    Publicado em 13/12/2007 às 18:42 | 155864 leituras

  1. TeamViewer disponível para Linux

    Publicado em 26/04/2010 às 1:27 | 124185 leituras

  1. Prévia do driver SQL Server para Linux

    Publicado em 30/11/2011 às 17:57 | 9987 leituras

  1. Lançada a Linux Magazine Especial Shell Script

    Publicado em 04/03/2011 às 11:39 | 15351 leituras

  1. Tráfego em IPv6 chega a 2% no Brasil

    Publicado em 03/06/2015 às 14:41 | 5276 leituras

  1. Kaspersky afirma que Stuxnet e Flame estão relacionados

    Publicado em 12/06/2012 às 16:55 | 9169 leituras

  1. Inteligência de negócios para o celular

    Publicado em 29/09/2011 às 12:00 | 7962 leituras

whitepapers

mais whitepapers