Java Magazine ed. 44
Refatoração no Eclipse Mantendo e melhorando a qualidade do código MARCOS ALEXANDRE MIGUEL MARCO ANTÔNIO PEREIRA ARAÚJO Durante o ciclo de vida de desenvolvimento e manutenção de produtos de software, as modificações em seu código fonte podem levar à queda da qualidade em relação ao projeto inicial. Essa perda de qualidade é geralmente causada por modificações com objetivos de curto prazo, como a correção de defeitos, ou por alterações realizadas sem a clara compreensão da concepção do sistema, como a revisão do projeto que nem sempre saem perfeitas na primeira versão do sistema ou resiste às mudanças dos requisitos impostos. Por exemplo, o desenvolvedor pode perceber que determinada classe está complexa demais e pode ser quebrada em várias subclasses. Esse problema pode ter surgido no projeto original devido à excessiva quantidade de responsabilidades ou então a classe cresceu à medida que ia adquirindo novas funcionalidades. Diante de situações como estas, a alteração sem a devida compreensão ou a falta de aplicação de técnicas específicas pode ocasionar novos problemas no projeto de software. Refatorar é o oposto a essa prática. Com ela é possível, a partir da necessidade de acomodar novas funcionalidades que não foram previstas inicialmente, ou ainda que necessite de melhorias de qualidade no seu projeto, transformá-lo em um código bem projetado. A refatoração, portanto, é um processo de alteração de um sistema de software de modo que o comportamento externo do sistema não mude, mas que sua estrutura interna seja aperfeiçoada. Em essência, quando se usam técnicas de refatoração, tende-se a melhorar o código-fonte após este ter sido escrito e modificado. Além disso, através da refatoração removem-se duplicidades, melhora-se a comunicação da equipe, e simplificam-se e flexibilizam-se rotinas, facilitando a manutenção e evitando a inclusão de novos defeitos. As refatorações são pontuais e modificam o código em pequenos passos de cada vez. Assim, se um erro é cometido, torna-se mais fácil consertá-lo. O efeito cumulativo dessas pequenas alterações pode melhorar consideravelmente a qualidade do produto. A versão 3.2 do ambiente de desenvolvimento Eclipse apresenta formas rápidas e eficientes para refatoração, além de outros recursos de apoio, como visualização de históricos e criação de scripts de refatorações já realizadas. Estes serão os assuntos abordados neste artigo.
Refatorações com o Eclipse No IDE Eclipse, no menu Refactor (Figura 1), ou no menu de contexto no editor de código, observam-se as possíveis operações de refatoração disponíveis no Eclipse 3.2.
Figura 1. Menu Refactor do Eclipse 3.2.
Através de exemplos práticos, pode-se ilustrar o uso de algumas destas operações. Assim, utilizaremos fragmentos de código de um sistema de Locação de Veículos. Esses trechos de código contêm situações indesejáveis, propositadamente inseridas, que serão corrigidas através do uso de refatorações.
Extract Superclass Código duplicado é um dos “maus cheiros” de código citados entre os problemas comuns em código-fonte. Uma forma de código duplicado são duas classes fazendo coisas semelhantes. Para resolver esse problema pode-se usar a refatoração Extract Superclass. Essa refatoração utiliza um mecanismo para simplificar esse problema através do conceito de herança da orientação a objetos. Nesse contexto, nota-se a necessidade da refatoração conforme pode ser observado nas Listagens 1 e 2, que representam fragmentos de duas classes, Caminhao e Automovel, com características semelhantes como ano, marca, modelo, nroChassi e placa. Vale salientar, porém, que a duplicação de pouco código (como um único atributo) pode não ser motivo suficiente para aplicar essa refatoração. Em caso de dúvida, verifique se as classes em questão possuem alguma semântica em comum (no exemplo, tanto Caminhao quanto Automovel são veículos). Listagem 1. Casse Caminhao public class Caminhao { private int nroEixos; private String ano; private String marca; private String modelo; private String nroChassi; private String placa; public public public public public public public public public public
float getValor() { return 50; } int getNroEixos() { return nroEixos; } void setNroEixos(int nroEixos) { this.nroEixos = nroEixos; } String getAno() { return ano; } void setAno(String ano) { this.ano = ano; } String getMarca() { return marca; } void setMarca(String marca) { this.marca = marca; } String getModelo() { return modelo; } void setModelo(String modelo) { this.modelo = modelo; } String getNroChassi() { return nroChassi; }
public void setNroChassi(String nroChassi) { this.nroChassi = nroChassi; } public String getPlaca() { return placa;} public void setPlaca(String placa) { this.placa = placa; } }
Listagem 2. Classe Automovel public class Automovel { private int nroPortas; private String ano; private String marca; private String modelo; private String nroChassi; private String placa; public public public public public public public public public public public
float getValor() { return 50; } String getAno() { return ano; } void setAno(String ano) { this.ano = ano; } String getMarca() { return marca; } void setMarca(String marca) { this.marca = marca; } String getModelo() { return modelo; } void setModelo(String modelo) { this.modelo = modelo; } String getNroChassi() { return nroChassi; } void setNroChassi(String nroChassi) { this.nroChassi = nroChassi; } String getPlaca() { return placa; } void setPlaca(String placa) { this.placa = placa; }
}
Para executar essa refatoração é necessário selecionar a classe ou as classes que terão os membros (atributos e/ou métodos) extraídos para uma superclasse, e utilizar a opção de menu Refactor>Extract Superclass. A caixa de diálogo mostrada (Figura 2) permitirá configurar várias opções para essa refatoração.
Figura 2. Caixa de diálogo da seleção da refatoração Extract Superclass.
O campo Superclass name permite informar o nome da classe que será criada e que será a superclasse da hierarquia. A opção Types to extract a superclass from permite selecionar mais de uma classe para aplicar a refatoração. Essa opção é útil neste exemplo, uma vez que tanto a classe Automovel quanto a classe Caminhao precisam da mesma operação de refatoração. A opção Specify actions for members permite a seleção de quais membros (atributos e/ou métodos) serão levados para a superclasse. O botão Add Required adiciona à lista de extração os membros adicionais requeridos para que a superclasse continue compilando. Os setters e getters de atributos, ao serem extraídos precisam do
atributo encapsulado e, ao clicar nessa opção, esse atributo é automaticamente marcado para solucionar as dependências para a extração. O botão Set Action permite definir como será a extração do método para a superclasse – ele pode ser extraído por completo (Extract) ou então declarado como abstrato na superclasse (Declare abstract in superclass), mantendo a implementação na subclasse. E se o projeto estiver configurado para compatibilidade com Java SE 5 ou superior, a implementação receberá a diretiva @Override. Nessa refatoração, além dos atributos indicados, foram selecionados ainda seus respectivos getter e setter, bem como o método getValor(). Devido a isso, após a execução da primeira fase da refatoração uma segunda janela (Figura 3) é mostrada permitindo a seleção dos métodos que serão extraídos da subclasse para a superclasse. Se apenas atributos forem selecionados para a extração, a caixa de Refactoring com a seleção dos métodos não será apresentada.
Figura 3. Caixa de diálogo da refatoração Extract Superclass.
A última fase da refatoração acontece quando a caixa de diálogo Refactoring (Figura 4) é apresentada com a visualização da refatoração antes de ser executada. Clicando no botão Finish, pode-se concluir a operação.
Figura 4. Caixa de diálogo com a visualização da refatoração Extract Superclass antes de aplicada.
As Listagens 3, 4 e 5 mostram o resultado após a execução dessa refatoração. Listagem 3. Classe Caminhao após a refatoração public class Caminhao extends Veiculo { private int nroEixos; public int getNroEixos() { return nroEixos; } public void setNroEixos(Integer nroEixos) { this.nroEixos = nroEixos; } }
Listagem 4. Classe Automovel após a refatoração. public class Automovel extends Veiculo { public int nroPortas; }
Listagem 5. Classe Veiculo criada após a refatoração public class Veiculo { private private private private private public public public public public public public public public public public
String String String String String
ano; marca; modelo; nroChassi; placa;
float getValor() { return 50; } String getAno() { return ano; } void setAno(String ano) { this.ano = ano; } String getMarca() { return marca; } void setMarca(String marca) { this.marca = marca; } String getModelo() { return modelo; } void setModelo(String modelo) { this.modelo = modelo; } String getNroChassi() { return nroChassi; } void setNroChassi(String nroChassi) { this.nroChassi = nroChassi; } String getPlaca() { return placa; } void setPlaca(String placa) { this.placa = placa; }
}
Encapsulate Field Uma das características básicas da Orientação a Objetos é o encapsulamento – ocultar detalhes internos da implementação de um objeto. Os benefícios do encapsulamento são muitos: clareza do código, minimização de erros, além de que partes encapsuladas poder ser modificada sem que os usuários da classe em questão sejam afetados. Como exemplo, pode-se introduzir um código de validação num setter de forma transparente para seus usuários. O encapsulamento é caracterizado pela visibilidade privada dos atributos de uma classe, acessíveis através de métodos de leitura (getXxx()) e modificação (setXxx()). Observa-se que a classe Automovel (Listagem 4) contém um atributo nroPortas que deveria estar encapsulado, mas ele está público e não há métodos para acessá-lo. Como uma boa prática de programação OO todo atributo deve ser encapsulado (privado), permitindo assim um menor acoplamento entre as classes e, consequentemente, um maior nível de reutilização. Para executar essa refatoração, é necessário selecionar o atributo a ser encapsulado, e utilizar a opção de menu Refactor>Encapsulate Field. A refatoração Encapsulate Field (Figura 5) substitui todas as referências a um atributo por seus setter e getter.
Figura 5. Caixa de diálogo da seleção Refatoração Encapsulate Field.
A opção Insert new methods after permite definir em qual parte do código serão colocados os novos métodos criados. A opção selecionada As first method indica que os novos métodos serão criados antes de qualquer código existente. Pode-se definir, ainda, o nível de visibilidade dos métodos criados, bem como permitir a geração de comentários automáticos para os novos métodos. Como antes, clicando no botão Preview é possível visualizar a caixa de diálogo (Figura 6) com as mudanças que serão feitas na classe.
Figura 6. Pré-visualização da refatoração Encapsulate Field.
Pull Up e Push Down Existem situações onde se torna necessário mover membros numa hierarquia de classes. Uma situação especial é exemplificada na classe Veiculo que possui um método contendo o valor da locação do veículo. Para exemplificar esta refatoração, considera-se um novo requisito, onde a implementação do método getValor() da classe Caminhao precisa ser tratada de forma diferente. Isso porque agora, o cálculo do valor da locação se deve em função do número de eixos, sendo que o valor máximo da locação não pode ultrapassar R$150,00. Portanto, precisa-se mover o membro que está na superclasse para ser definido na subclasse. Além disso, é possível informar o método como abstrato na superclasse, forçando posteriormente sua implementação para as classes que dela herdam. As refatorações Pull Up e Push Down movem os membros para uma classe de destino, excluindo os mesmos da classe original, se não forem marcados como abstratos. Para executar uma dessas refatorações, é necessário selecionar os membros (atributos e/ou métodos) e utilizar a opção de menu Refactor>Push Down ou Refactor>Pull Up. Uma caixa de diálogo (Figura 7) mostra os membros da classe atual que podem ser movidos.
Figura 7. Seleção para refatoração Push Down.
A refatoração Push Down move os membros para a classe imediatamente abaixo da classe atual. A refatoração Pull Up permite a seleção da classe alvo, na hierarquia de classes, para onde o membro será movido. O botão Set Action permite definir como será a extração do método para a superclasse, ele pode ser movido por completo (Push down) ou então ficar definido como abstrato na classe (Leave abstract declaration). Clicando no botão Preview pode-se visualizar a caixa de diálogo (Figura 8) com as mudanças que serão feitas nas classes, e ainda selecionar em quais subclasses serão efetivadas as mudanças.
Figura 8. Caixa de diálogo com a visualização da refatoração Push Down antes de aplicada.
Após essa refatoração, a classe Veiculo terá um método abstrato getValor() (Listagem 6), e as classes Automovel e Caminhao conterão as implementações deste método conforme as Listagens 7 e 8. O método que foi movido recebeu a notação @Override, que é específica ao Java SE 5 ou superior e não é obrigatória, indicando que o método esta redefinindo um método da superclasse. Esta anotação evita erros como alterar manualmente o nome do método-base e não refletir a alteração nos derivados. Para abrigar o novo requisito, o método Caminhao.getValor() foi modificado conforme a Listagem 9.
Listagem 6. Listagem parcial do código-fonte da classe Veiculo após a refatoração. public abstract class Veiculo { private String ano; private String marca; private String modelo; private String nroChassi; private String placa; public abstract float getValor(); ... }
Listagem 7. A classe Automovel após a refatoração. public class Automovel extends Veiculo private int nroPortas;
{
public void setNroPortas(int nroPortas) { this.nroPortas = nroPortas; } public int getNroPortas() { return nroPortas; } @Override public float getValor() { return 50; } }
Listagem 8. A classe Caminhao após a refatoração. public class Caminhao extends Veiculo { int nroEixos; public int getNroEixos() { return nroEixos; } public void setNroEixos(int nroEixos) { this.nroEixos = nroEixos; } @Override public float getValor() { return 50; } }
Listagem9. O método Caminhão.getValor() após a modificação em função do novo requisito. @Override public float getValor () { if (50 * getNroEixos() > 150) { return 150; } else { return 50 * getNroEixos(); } }
Extract Local Variable Expressões complexas podem se tornar muito difíceis de ler, e sua repetição no código pode complicar ainda mais o entendimento do propósito de um método. Nesse caso extrair a expressão para uma variável local pode tornar o código mais legível, simplificando a manutenção. A refatoração Extract Local Variable pode ser usada para criar uma variável que representa uma expressão selecionada e substituir a seleção por uma referência à nova variável. A classe Caminhao possui no método getValor() a expressão “50 * getNroEixos()”, que possui um grau de complexidade baixo mas, no entanto, se repete ao longo do método. Pode assim se enquadrar nos padrões para essa refatoração, e a expressão deve ser substituída por uma variável que expresse seu objetivo. Para executar essa refatoração, é necessário selecionar a expressão no bloco de código e utilizar a opção de menu Refactor>Extract Local Variable. Por padrão, todas as referências serão substituídas, a menos que a opção Replace all, mostrada na caixa de diálogo da Figura 9, seja desmarcada. Se essa opção for desmarcada, somente a expressão selecionada será substituída pela variável. Recomenda-se também marcar a variável local com final, garantindo assim que a variável temporária receberá atribuição de valor apenas uma vez.
Figura 9. Caixa de diálogo com as opções da refatoração Extract Local Variable.
Clicando no botão Preview pode-se visualizar a caixa de diálogo (Figura 10) com as mudanças que serão feitas no método.
Figura 10. Caixa de diálogo com a visualização da refatoração Extract Local Variable antes de aplicada.
Rename Métodos devem ser nomeados de uma maneira que comuniquem sua intenção ou revelem seu propósito. Código fonte de boa qualidade é construído de forma que possa ser entendido por desenvolvedores e dar bons nomes é importante nesse aspecto. A refatoração Rename (Figura 11) busca e modifica em todo o projeto por referências ao membro refatorado. Pode-se refatorar com essa opção métodos, parâmetros, atributos, variáveis locais, tipos, constantes, enumerados, classes, pacotes e pastas de código fonte. O método Veiculo.getValor() não expressa muito bem a sua intenção; alguém poderia imaginar que se trata do preço de compra do veículo. Isso poderia ser esclarecido por comentários, mas uma das características de código bem escrito é que dispensa comentários triviais – a semântica do código, pelo menos em algum grau, é evidente pelos seus identificadores e estrutura. Pode-se, então, renomear o método para algo mais sugestivo, como getValorLocacao(). Para executar essa refatoração, é necessário selecionar o membro da classe e utilizar Refactor>Rename.
Figura 11. Caixa de diálogo da refatoração Rename.
No exemplo usado, a alteração no nome do método foi feito na superclasse Veiculo e se refletiu automaticamente em todas as subclasses e nas classes que utilizam esse método.
Extract Method Métodos grandes demais são problemáticos, pois frequentemente contêm muitas informações que ficam escondidas pela complexidade da lógica associada. Ferramentas de coleta de métricas de software que avaliam a complexidade do modelo e fazem uma análise quantitativa do código podem detectar que esses métodos precisam de uma atenção redobrada ou mesmo serem redefinidos. Métricas como Complexidade Ciclomática podem indicar métodos muito complexos ou longos, e serão automaticamente ajustadas após o uso dessa refatoração que substituirá um método longo e complexo por vários métodos curtos e simples. A refatoração Extract Method cria um novo método que contém as indicações ou a expressão selecionadas atualmente e substitui a seleção por uma referência ao método novo. Esta refatoração é útil para limpar métodos longos, desordenados, ou muito complexos, aumentando a clareza e a compreensão do seu funcionamento. Possibilita também reutilizar os métodos criados em vários pontos do sistema. A classe Contrato contém um método que imprime o contrato atual do cliente (Listagem 10), mas o código tende a ficar extenso e, por isso, deve-se refatorá-lo. Para executar essa refatoração, é necessário selecionar a parte de código que será extraída e utilizar a opção do menu Refactor>Extract Method. O código será extraído em três métodos, um que irá imprimir o cabeçalho, outro o corpo e, por fim, o rodapé do relatório. Listagem 10. O método imprimirContrato() antes da refatoração import java.util.ArrayList; import java.util.Date; import static java.lang.System.*; ... public void imprimirContrato() { float total = 0; // Cabecalho do Relatório out.println("** Contrato de Locação **"); out.println("Data da Locação: " + getData()); out.println("Cliente .......: " + getCliente().getNome()); out.println("CPF ...........: " + getCliente().getCpf()); out.println("CNH ...........: " + getCliente().getCnh()); // Corpo do Relatório out.println("Veiculos Locados: " + getCliente().getCnh()); for (Veiculo v : getVeiculo()) { out.println("->Modelo: " + v.getModelo()); out.println("->Marca : " + v.getModelo()); out.println("->Ano ..: " + v.getAno()); out.println("->Chassi: " + v.getNroChassi()); out.println("->Chassi: " + v.getPlaca()); out.println("->Valor : " + v.getValorLocacao()); total = v.getValorLocacao(); } // Rodape do Relatório out.println("Total da Locação : " + total); out.println("Nro do Contrato .: " + getNroContrato()); }
Para um melhor entendimento do método imprimirContrato() se vê a necessidade de comentar qual parte do código tem que função. Quando se necessita comentar um código para que este possa demonstrar seu objetivo, pode-se tentar refatorá-lo. Quebrar seções longas do código em métodos aumenta a legibilidade, a manutenibilidade e até o reuso.
Como primeira parte da extração de método, será criado um novo método que imprime o cabeçalho do relatório. O Extract Method (Figura 13) pegará automaticamente uma lista dos parâmetros de acordo com as declarações das variáveis locais e a parte onde estava o código será substituída por uma chamada ao método criado.
Figura 13. Caixa de diálogo da seleção Refatoração Extract Method.
Clicando no botão Preview pode-se visualizar a caixa de diálogo com as mudanças que serão feitas na classe. Ao extrair o corpo do relatório para um novo método pode-se notar que a refatoração irá tratar um caso diferente, o aparecimento de variáveis locais. Quando a presença de variáveis locais for detectada, a caixa de diálogo (Figura 14) será apresentada permitindo a alteração ou a mudança da posição das variáveis necessárias para que a refatoração seja executada com sucesso. Além disso, pode-se marcar o método como tendo a necessidade de tratamento de exceções e ainda gerar um comentário para o mesmo.
Figura 14. Caixa de diálogo da Refatoração Extract Method com os parâmetros.
A refatoração irá buscar no código todas as referências às variáveis que sejam locais no escopo do método do código-fonte. Se existirem variáveis locais usadas apenas dentro do código extraído,
essas serão declaradas dentro do novo método com variáveis temporárias. São passadas para o novo método como parâmetros as variáveis de escopo local que são lidas pelo código extraído. Uma terceira refatoração será extrair o rodapé do relatório que pode ser feito como no caso anterior, selecionando a parte do código a ser extraída e usando Extract Method. O código resultante após as refatorações é apresentado na Listagem 11, onde se pode ver como foi aplicada a refatoração em várias partes do código do método que imprime o contrato. São gerados assim novos métodos que separadamente imprimem o cabeçalho, o corpo e o rodapé do relatório. Analisando o código do método imprimirContrato() pode-se notar que, com o uso da refatoração, sua legibilidade aumentou e, portanto, qualquer manutenção futura no mesmo será facilitada. Além do beneficio imediato observado, essa refatoração será obrigatória para que não ocorra duplicação de código desnecessária caso uma subclasse de Contrato necessite customizar apenas o corpo do Contrato mas não o cabeçalho e rodapé, mostrando assim mais um forte motivo para se utilizar esta refatoração. Listagem11. O método imprimirContrato() e demais métodos criados após sua refatoração. public void imprimirContrato() { float total = 0; cabecalhoContrato(); total = corpoContrato(total); rodapeContrato(total); } private void cabecalhoContrato() { out.println("** Contrato de Locação **"); out.println("Data da Locação: " + getData()); out.println("Cliente .......: " + getCliente().getNome()); out.println("CPF ...........: " + getCliente().getCpf()); out.println("CNH ...........: " + getCliente().getCnh()); } private float corpoContrato(float total) { out.println("Veiculos Locados: " + getCliente().getCnh()); for (Veiculo v : getVeiculo()) { out.println("->Modelo: " + v.getModelo()); out.println("->Marca : " + v.getModelo()); out.println("->Ano ..: " + v.getAno()); out.println("->Chassi: " + v.getNroChassi()); out.println("->Chassi: " + v.getPlaca()); out.println("->Valor : " + v.getValorLocacao()); total = v.getValorLocacao(); } return total; } private void rodapeContrato(float total) { out.println("Total da Locação : " + total); out.println("Nro do Contrato .: " + getNroContrato()); }
Histórico de Refactoring O histórico de refatorações (Figura 15) é uma ferramenta de apoio às refatorações existentes. Indica todas as refatorações executadas no workspace e oferece a opção de suprimir refatorações do histórico, além de classificá-las por data e hora. Esses históricos são úteis para a criação de scripts de refatorações e para se manter um controle das refatorações aplicadas ao sistema.
Figura 15. Caixa de diálogo da seleção Refatoração History.
Criação de Scripts de Refactoring
As refatorações contidas no histórico podem ser selecionadas na lista de refatorações aplicadas ao workspace e exportadas para um arquivo de script (Figura 16). Também é possível visualizar somente as refatorações de um projeto individual, com Properties>Refactoring History.
Figura 16. Caixa de diálogo da seleção da Refatoração Create Script.
Tais scripts fazem parte das ferramentas de apoio às refatorações existentes. Podem ser usados em cenários diferentes tais como reparo automático quando códigos são perdidos e recuperados na versão antes da aplicação das refatorações. Para criar um script deve-se selecionar o comando Refactor>Create Scripts. Podem ser selecionadas quais as refatorações serão salvas bem como a localização do arquivo de script, que pode ser copiado para a área de transferência ou salvo em um arquivo. A Listagem 12 mostra o conteúdo de um arquivo de script após a refatoração. Esse script foi gerado selecionando apenas uma refatoração Encapsulate field do atributo nroPortas, apresentada na listagem das refatorações executadas. Listagem 12. Listagem do conteúdo do arquivo de script após as refatorações.
Execução de Scripts de Refactoring
Os scripts salvos podem ser reaplicados ao projeto de acordo com a necessidade ou conveniência. A aplicação de scripts pode ser útil após uma perda de informações, ou então ao recuperar o códigofonte o desenvolvedor notar que o conjunto de refatorações aplicados na última modificação do mesmo não estão mais presentes. Para aplicar as refatorações salvas de um script utiliza-se a opção do menu Refactor>Apply Script, selecionando o caminho onde o arquivo contendo o script foi salvo. Após essa seleção, ao clicar no botão Next, pode-se visualizar e selecionar as refatorações que serão aplicadas ao código.
Conclusões A interação resultante das aplicações das operações de refatoração leva a uma melhora significativa no projeto de software, que permanece fácil de manter na medida em que o desenvolvimento continua. A refatoração também está altamente relacionada a uma boa rotina de testes automatizados. Testes funcionais e unitários verificam o comportamento observável do software e o correto funcionamento de seus métodos. Com esses tipos de testes pode-se avaliar se a refatoração aplicada não modificou em nada o comportamento do sistema, garantindo assim a qualidade das refatorações aplicadas. Note que as refatorações "puras", feitas exclusivamente pelas ações de refatoração do Eclipse, nunca introduzirão bugs – exceto em casos especiais, como código que usa reflection, que não é detectado e corrigido pelo Eclipse – mas é mais comum misturarmos e alternarmos refatorações com ajustes manuais, daí a utilidade dos testes unitários. Foi mostrado também o uso de algumas operações de refatoração disponíveis no ambiente Eclipse e que auxiliam equipes de desenvolvimento na manutenção de sistemas, tornando mais clara a compreensão do código-fonte. Outros ambientes para desenvolvimento Java, como IntelliJ e o NetBeans, incorporam em suas IDEs operações de refatoração similares às aqui apresentadas. Links www.refactoring.com Site com informações sobre refatoração www.martinfowler.com Site oficial de Martin Fowler, autor do livro “Refatoração - Aperfeiçoando o projeto de código existente” que contém um catálogo com 72 refatorações, entre essas as que foram vistas neste artigo.
Marcos Alexandre Miguel (
[email protected]) é Graduando do Curso de Bacharelado de Sistemas de Informação do Centro de Ensino Superior de Juiz de Fora (CES/JF) e desenvolvedor da Projetus Informática Ltda, onde atua na área de soluções para automação comercial e contábil.
Marco Antônio Pereira Araújo (
[email protected]) é Doutorando e Mestre em Engenharia de Sistemas e Computação pela COPPE/UFRJ, Especialista em Métodos Estatísticos Computacionais e Bacharel em Matemática com Habilitação em Informática pela UFJF, Professor dos Cursos de Bacharelado em Sistemas de Informação do Centro de Ensino Superior de Juiz de Fora, da Faculdade Metodista Granbery e da Universidade Severino Sombra, Professor do Curso de Tecnologia em Processamento de Dados da Fundação Educacional D. André Arcoverde, Analista de Sistemas da Prefeitura de Juiz de Fora.