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

Seminário sobre gestão de privilégios do Linux dá direito a certificado CPE

Publicado em: 23/05/2017 às 10:35 | leituras |

O evento irá abordar a forte disseminação de sistemas Linux em toda a estrutura de informação e mostrará a importância de técnicos da área serem capazes de identificar rotas, especificar controles de acesso para usuários Linux e monitorar a atividade privilegiada do usuário ao longo da rede de informação e, especialmente, na complexidade da nuvem. Participantes poderão requerer gratuitamente os créditos de CPE (Continuing Professional Education).

Novas vagas para os minicursos do WikiLab

Publicado em: 16/05/2017 às 11:59 | leituras |

Novas vagas abertas para os minicursos do WikiLab. Todos que já apoiaram ou apoiarem o projeto WikiLab no Catarse (com qualquer valor) podem participar.

Novo evento "Universidade Livre" será realizado em Belém/PA em 06/05/2017

Publicado em: 28/04/2017 às 11:19 | leituras |

Novo evento sobre Software Livre será realizado no Instituto de Estudos Superiores da Amazônia (IESAM).

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.


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 | 415626 leituras

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

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

  1. Soluti Certificação Digital em busca de especialista Linux

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

  1. Software público brasileiro na Linux Magazine Especial

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

  1. Lançado o phpBB 3

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

  1. Google Earth ganha nova versão para Android

    Publicado em 24/08/2010 às 14:48 | 7627 leituras

  1. Empresas aumentam uso Linux para reduzir custos, revela pesquisa

    Publicado em 20/09/2013 às 13:28 | 9489 leituras

  1. Falta de profissionais ameaça projetos em TI

    Publicado em 23/04/2014 às 9:59 | 8623 leituras

  1. OpenShift aberto!

    Publicado em 03/05/2012 às 12:55 | 11649 leituras

  1. Versão beta do Internet Explorer 9 será lançada em setembro

    Publicado em 02/08/2010 às 14:34 | 7488 leituras

whitepapers

mais whitepapers