Para iniciar o processo de refatoração, antes é preciso formar uma base sólida, com o auxílio de testes, técnicas e ferramentas. Toda refatoração segue passos básicos: criação de testes, identificação dos pontos de melhoria, aplicação de técnicas de refatoração, execução de testes e validação das alterações.
Abaixo estão listadas algumas técnicas empregadas na refatoração de códigos, essas técnicas foram catalogadas por Martin Fowler em seu livro (Refatoração: Aperfeiçoamento e Projeto), e utilizam fortemente os princípios da Orientação a Objetos. Nele estão listadas as refatorações mais corriqueiras e servem de base para equipes que começarão a refatorar seu código.
Refatoração : Extrair Método (ExtractMethod)
Quando você têm partes similares do código que podem ser agrupadas, geralmente código que está duplicado, então você deve mover essas partes para um novo método que tenha um nome que faça sentido.
A principal motivação para esta refatoração é eliminar do código métodos muito grandes que realizam mais de uma tarefa e geralmente precisam estar cheios de comentários para que seja compreendido.
Métodos menores aumentam a granularidade do código e quando bem nomeados aumentam a clareza do que foi escrito. A nomeação de métodos é vital para que esta técnica funcione, o nome deve dizer claramente o que o método se propõe a fazer, e o tamanho do nome do método não deve ser um entrave, utilize nomes tão grandes quanto necessário (Ex.: ObterUrlDeRedirecionamentoParaSiteParceiro(codigoParceiro)).
Refatoração : Mover Método (Move Method)
Quando você possui um método que será utilizado muitas vezes por outra classe diferente da classe na qual ele foi definido, crie um método similar nesta classe que o está utilizando, depois copie o corpo do método copiado para o novo método, então substitua as chamadas para utilizarem o método local. Pode-se também avaliar se o método original deve ser preservado ou se pode ser eliminado.
Na imagem abaixo vemos o método “aMethod” foi retirado da classe de origem “Class1” e movido para a classe “Class2”, onde ele faz mais sentido existir.
Refatoração : Mover Atributo (Move Field)
Similar à técnica Mover Método (seção 2.3.2), Mover Atributo é aplicada quando outra classe diferente da classe onde o atributo foi definido, o utiliza muitas vezes. Nesse caso devemos apenas copiar o atributo de uma classe para outra e alterar as chamadas para que passem a utilizar o atributo local. Mais uma vez cabe avaliar se o atributo original deve ou não ser eliminado.
Abaixo vemos, o atributo “aField” foi retirado da classe de origem “Class1” e movido para a classe de destino “Class2”, onde ele faz mais sentido existir.
Refatoração : Extrair Classe (Extract Class)
Quando você possui uma classe que está executando a tarefa de duas, então crie uma nova classe, depois mova todos os atributos relevantes para esta nova classe.
A motivação desta técnica é bastante óbvia, sempre ouvimos falar que cada classe deve ser coesa e ter objetivos bastante claros, mas na prática as classes crescem. Quando um desenvolvedor adiciona uma nova funcionalidade em certa classe, talvez ela não parecesse tão errada, mas com o tempo esta funcionalidade irá crescer, e trazer mais responsabilidades para a classe.
Ao extrair estas responsabilidades da classe e a colocando em outra, há um ganho em coesão, legibilidade e reutilização do código.
Abaixo os atributos “officeAreaCode” e “officeNumber” foram extraídos da classe “Person”, em seguida esses dois atributos foram encapsulados em uma nova classe “TelephoneNumber”, em seguida um uma referência de para a classe “TelephoneNumber” foi adicionada a classe “Person”.
Refatoração : Encapsular Atributo (Encapsulate Field)
Quando um atributo é acessado diretamente e isto parecer ser estranho, devem-se criar métodos de acesso a este atributo.
Existem duas escolas que defendem meios diferentes de acessar atributos de uma classe. A primeira diz que os atributos expostos devem ser acessados diretamente, pois isto torna o código mais legível. A segunda diz que devemos criar métodos de acesso a cada atributo exposto da classe, pois isto facilita que subclasses sobrescrevam os métodos de acesso.
O melhor a fazer neste caso é discutir com outros membros da equipe para determinar qual a melhor maneira de dar acesso aos atributos, de modo a manter coerência com o resto do software.
Uma boa maneira de resolver este problema é criar os atributos sendo acessados diretamente e quando isto começar a parecer estranho, substituir por métodos de acesso.
Quando estes atributos que são acessados estão em uma superclasse, primeiro deve-se encapsular o atributo internamente, na superclasse, e em seguida, sobrescrever o método de acesso na classe derivada.
Na Figura 2.4, o atributo “_name” foi encapsulado dentro dos métodos de acesso “getName()” e “setName()”, de modo a diminuir a dependência por parte de outras classes a este atributo.
Refatoração : Renomear Método (Rename Method)
Quando o nome de um método não revela qual a sua intenção, deve-se altera-lo imediatamente, de modo que o novo nome deve descrever claramente o que ele se propõe a fazer.
Segundo Martin Folwer (2004, p.221)
“… lembrem-se códigos são escritos primeiramente para humanos, computadores vem em segundo lugar…”.
Assim como na técnica Extrair Método (seção 2.3.1), o tamanho do nome não deve ser um impeditivo, contanto que ele não deixe dúvidas sobre o que o método faz. (Ex.: listarFichasTecnicasDeEventosPorSuaCategoria(codigoDaCategoria))
Na Figura 2.5, o método “getinvcdtlmt()” teve o seu nome alterado para “getInvoiceableCreditLimit()”, de modo a dar mais clareza do seu comportamento e melhorar a legibilidade do código. (Ex.: listarFichasTecnicasDeEventosPorSuaCategoria(codigoDaCategoria))
Estas são as técnicas frequentes propostas por Martin Fowler em seu livro.
Joshua Kirievsky também apresenta um rico catalogo de refatorações focadas em padrões de projeto, em seu livro Refatoração para Padrões. Neste livro podemos ver refatorações como Internalizar Acesso Único (p.143), Formar Método gabarito (p.237), Substituir Lógica
Condicional por Estratégia, Extrair Parâmetro (p.381), Extrair Adaptador (p.290), entre outras.
Joshua Bloch em seu livro Java Efetivo lista 78 boas práticas em na linguagem Java, que funcionam também como uma lista de refatorações.
Em um próximo Post eu listarei mais algumas técnicas de refatoração.
Comentários