Artigo Java Magazine 46 - Refactoring: da Teoria à Prática

Você precisa estar logado para dar um feedback. Clique aqui para efetuar o login
Para efetuar o download você precisa estar logado. Clique aqui para efetuar o login
Confirmar voto
0
 (0)  (0)

Como como utilizar técnicas de refactoring para simplificar a manutenção e melhorar a qualidade e a evolução do seu código.

Esse artigo faz parte da revista Java Magazine edição 46. Clique aqui para ler todos os artigos desta edição

Atenção: por essa edição ser muito antiga não há arquivo PDF para download.Os artigos dessa edição estão disponíveis somente através do formato HTML. 

Mão na Massa

Refactoring: da Teoria à Prática

Melhorando a estrutura do seu código-fonte

 

Utilizando técnicas de refactoring para simplificar a manutenção e melhorar a qualidade e a evolução do seu código

 

O refactoring (ou refatoração) é uma atividade comum em processos ágeis como o Extreme Programing, nos quais as mudanças no código são constantes. Essa técnica, no entanto, não é utilizada apenas em softwares desenvolvidos sob esses processos. Seu uso é muito mais abrangente e traz como conseqüência direta um código mais limpo, de manutenção mais fácil e com maior qualidade.

Neste artigo veremos os conceitos de refactoring – quando refatorar uma aplicação e como fazê-lo – e nos apoiaremos nos comandos de refatoração do IDE Eclipse para demonstrar tais tarefas. Embora seja usado um IDE para automatizar alguns passos, o enfoque deste artigo será nas atividades de refatoração em si, de forma independente de ferramentas, bem como nos conceitos fundamentais envolvidos.

 

O Contexto

Quem nunca se deparou com um código no qual a alteração de um simples método levou à modificação de dezenas de linhas de código? E quando foi necessário manter um método "faz tudo" com 500 linhas? Isso sem falar daqueles métodos com dezenas de parâmetros, códigos duplicados e algoritmos que ninguém consegue entender.

Esses sintomas são denominados "badsmells" (maus cheiros) pelos especialistas em refactoring, e resultam principalmente de um design ruim, ou mesmo da falta de design. Os problemas ficam evidentes quando se deseja incluir uma nova funcionalidade ou alterar o código existente: normalmente é difícil (ou até impossível) mudar o código sem quebrar o funcionamento do programa.

 

Mas por que alterar?

Suponha que você vem utilizando um componente qualquer, que tem funcionado adequadamente ao longo de vários anos. Durante esse período, o componente foi usado em diversos sistemas e demonstrou funcionamento e performance adequados, o que o tornou bastante confiável.

Agora seu componente será utilizado em um novo sistemas, e para isso algumas alterações deverão ser efetuadas por questões de compatibilidade. O autor do componente não está mais na empresa, e coube a você assumir a nova tarefa.

Só que, se o componente não tiver sido bem projetado, o que parecia uma alteração simples pode se tornar um pesadelo: sistemas com design ruim são difíceis de alterar. Nestes casos, entender o que deve ser mudado não é uma tarefa simples, e são grandes as chances de se introduzir bugs ao longo do processo.

Cria o código é apenas o início. Todos nós sabemos que os sistemas evoluem, e que o que foi acordado com o cliente hoje nem sempre valerá amanhã. Por isso, código bom não é código que "apenas funciona": é código que também é simples de entender, alterar e estender.

As técnicas de refactoring melhoram o design do software e facilitam seu entendimento. Como conseqüência, o tornam mais simples e facilitam a descoberta de bugs.

 

Entendendo a técnica

Refactoring é uma técnica poderosa, e que precisa ser aplicada com cuidado. O princípio é simples: pequenas alterações são efetuadas de forma incremental no código, enquanto a funcionalidade do sistema permanece inalterada.

A capacidade de refactoring está presente em todos os IDEs modernos, com diferentes graus de sofisticação. Em geral as operações de refactoring automatizadas pelas IDEs são bastante seguras e podem ser efetuadas sem receio.

Dentre os IDEs livres, o Eclipse e o NetBeans destacam-se pela diversidade de comandos, possuindo funcionalidades equivalentes (o plug-in Jackpot aumenta bastante o poder de refactoring do NetBeans, mas deve ser instalado à parte1). Já o IntelliJ IDEA (um produto proprietário) é o IDE com maior capacidade de refactoring existente.

Todas as operações de refactoring disponíveis nas ferramentas de desenvolvimento seguem o catálogo proposto por Martin Fowler (veja as referências ao final do artigo). Porém, como veremos ao longo do texto, nem todas possuem suporte automatizado.

 

Refatorando

A melhor maneira de fixar os conceitos de refactoring é praticando. A Listagem 1 apresenta a classe CartaoUtil. Nela, o método validar() verifica números de cartões de crédito e imprime uma mensagem indicando se o número do cartão é válido ou não. Os parâmetros para validação são a bandeira do cartão (Visa, MasterCard, American Express ou Diners), além de seu número e data de validade.

 

Listagem 1. Classe cartãoUtil original                                                                                    

 

package br.com.jm.refactoring;

 

import java.text.”;

import java.util.*;

 

public class CartaoUtil {

    public static final int VISA = 1;

    public static final int MASTERCARD = 2;

    public static final int AMEX = 3;

    public static final int DINERS = 4;

    public static final String CARTAO_OK = “Cartão válido”;

    public static final String CARTAO_ERRO = “Cartão inválido”;

 

    public String validar(int bandeira, String numero, String validade) {

 

       boolean validade ok = false;

 

      // ----- VALIDADE -----

      Date dataValidade = null;

      try {

          dataValidade = new SimpledateFormat(“MM/yyyy”).parse(validade);

      }   catch (ParseException e) {

           return CARTAO_ERRO;

      }

      Calendar calValidade = new GregorianCalendar();

      calValidade.setTime(dataValidade);

 

      // apenas mês e ano são utilizados na validação

      Calendar calTemp = new GregorianCalendar();

      Calendar calHoje = (GregorianCalendar) calValidade.clone();

      calHoje.set(Calendar.MONTH, calTemp.get(Calendar.MONTH));

      calHoje.set(Calendar.YEAR, calTemp.get(Calendar.YEAR));

 

      validadeOK = calHoje.before(calValidade);

 

      if (!validadeOK) {

          return CARTAO_ERRO;

     }

     else {

           // ---- PREFIXO E TAMANHO -----

           String formatado = “”;

 

          // remove caracteres não-numéricos

          for (int i = 0; i < numero.length(); i++) {

              char c = numero.chartAt(i);

              if (Character.isDigit(c) {

                 formatado += c;

              }

          }

 

          boolean formatoOK = false;

 

          switch (bandeira) {

          case VISA: // tamanhos 13 ou 16, prefixo 4.

             if   (formatado.startsWith(“4”) &&

                  (formatado.length() == 13 ||

                     formatado.length() == 16 )) {

                 formatoOK = true;

             } else {

                formatoOK = false;

             }

             break;

          case MASTERCARD: // tamanho 16, prefixos 51 a 55

             if  ((formatado.startsWith(“51”) ||

                formatado.startsWith(“52”) ||

                formatado.startsWith(“53”) ||

                formatado.startsWith(“54”) ||"

A exibição deste artigo foi interrompida :(
Este post está disponível para assinantes MVP

 
Você precisa estar logado para dar um feedback. Clique aqui para efetuar o login
Receba nossas novidades
Ficou com alguma dúvida?