Análise dos Refatoramentos
jMemorize 1.2.3
Professor:
Equipe:
Adalberto Júnior
Fábio Leal
Jeysibel Dantas
Renato Almeida
Solon Aguiar
Rohit Gheyi
Julho / 2010
106 1. Objetivo
Ao longo desse documento procuramos evidenciar quais foram os refatoramentos
aplicados ao código do sistema jMemorize. A versão do sistema tomada como base
para a aplicação dos refatoramentos foi a 1.2.3. As modificações no código da
aplicação foram motivadas por ferramentas de análise estática, tais como o Findbugs e
o Metrics. Seguimos os seguintes passos para a aplicação de refatoramentos: Análise
do código por ferramentas de análise estática; Verificação do código (descobrir se há,
de fato, motivos para mudança nos trechos de código); Rodar testes (do Sistema e os
gerados pelo Randoop); Realizar Mudanças; Rodar testes novamente. Seguindo essa
rotina pudemos perceber que o processo de refatoramento torna-se mais seguro.
2. Refatoramentos
Durante o processo de estudo da evolução do jMemorize foram feitos
refatoramentos tanto de forma automática quanto de forma manual. Os refatoramentos
assistidos por ferramentas foram realizados pelas ferramentas de refatoramentos da
IDE Eclipse.
Esses refatoramentos foram guiados pelos resultados das ferramentas de análise
(Findbugs, Randoop). Isso ocorreu devido ao fato de que realizar refatoramentos
sobre um sistema desconhecido sem auxilio de guia é uma tarefa complicada e
demorada. Essa também foi uma forma utilizada para confrontar as saídas dessas
ferramentas com resultados reais.
A seguinte imagem representa a análise inicial do Plugin Metrics (mais detalhes
sobre essa análise inicial podem ser vistos no documento de Análise de Qualidade).
Figura 1 – Análise do código original
107 Durante o processo de refatoramento, foram utilizados, dentre outros, os seguintes
tipos de transformações:
•
•
•
•
•
Remoção de atributos não utilizados;
Tratamento adequado de exceções;
Fechamento de Streams que permaneciam abertas quando não era
necessário;
Melhoramento de performance do sistema (através das dicas do Findbugs);
Rename de atributos e métodos.
Exemplos dos refatoramentos aplicados
Nas imagens seguintes, o lado esquerdo representa o código original e o lado direito o
código refatorado. Isso foi feito para facilidade de comparação.
1) Exclusão de checagens desnecessárias ao longo do código.
Figura 2 – Checagem desnecessária da nulidade de Lesson
2) Evitar criação de objetos desnecessários: Esse tipo de modificação pode ter
alterado de maneira decisiva a performance do sistema, uma vez que
encontrávamos essa situação dentro de loops.
Figura 3 – Criação de objetos desnecessários
3) Má utilização da API: Ao invés de usar classes superiores como o entrySet, o
código faz uso de keySets. Isso também foi verificado para “Lists”
Figura 4 – Má utilização da API
4) Criação de um Comparator sem fazer uso da interface Serializable: A
documentação de Java recomenda fortemente que seja implementada a interface
serializable em objetos do tipo Comparator.
Figura 5 – Má implementação de objetos Comparators
5) Tratamento incorreto para exceções: Muitos trechos de código da aplicação não
têm o devido tratamento de exceções.
Figura 6 – Tratamento de exceções indevido
108 Feitos os refatoramentos propostos, no total, 20 entidades sofreram alguma
mudança. Os tipos de refatoramentos propostos mostram que tratamos tanto de
refatoramentos high level, como nos casos de rename de atributos, como
refatoramentos low level, que foi o caso de rename de métodos e tratamento de
exceções, por exemplo. Dependendo do impacto das entidades e métodos refatorados,
esses refatoramentos podem ser classificados em local e global.
Enquanto executávamos os refatoramentos percebemos que as ferramentas de
análise estática, apesar de servirem como um bom guia, não são 100% confiáveis. A
implementação de simples refatoramentos (feitos tanto de forma manual, como de
forma automática) sugeridos pelo Findbugs faziam com que o sistema mudasse de
comportamento ao lançar exceções inesperadas. Esse tipo de erro foi possível de
captar mediante a execução dos testes gerados pelo Randoop após a realização do
refatoramento. O objetivo desse teste de regressão era justamente checar a
preservação do comportamento.
Sendo assim, ratificamos aqui a importância de se ter uma boa coleção de testes
ao refatorar um sistema real. Se o processo de refatoramento, conforme foi exposto
em sala de aula, não for seguido à risca, desenvolvedores podem perder bastante
tempo à procura de faltas geradas por refatoramentos originalmente sugeridos por
ferramentas.
Podemos ver, na Figura 7, a maneira como o software evoluiu após os
refatoramentos. Ao fazer uma breve comparação com os resultados obtidos para o
sistema não refatorado, podemos traçar um paralelo entre o valor anterior e o obtido
após refatormarmos o sistema. Dessa maneira, percebemos que os números após os
refatoramentos tornaram-se melhores (segundo nossas métricas) quando comparados
às medidas sugeridas pelo plug-in Metrics antes do refatoramento. Mais detalhes
podem ser vistos no documento de Análise de Qualidade.
Figura 7 – Análise do código refatorado
109 As mudanças feitas após a utilização das ferramentas FindBugs e Randoop
totalizaram 90 LOC. Tudo o que foi modificado pode ser observado no endereço:
http://pastebin.com/RbyP1yY5, onde é feita a comparação da versão inicial com a
versão refatorada.
110 
Download

Análise dos Refatoramentos jMemorize 1.2.3