Kent Beck, um dos criadores da Programação Extrema, afirma que refatoração deve ser utilizada quando o “código cheirar mal” (do inglês bad smells in code).
Alguns indícios já possuem uma aceitação ampla para promover refatoração:
- Código duplicado (duplicated code)
- Método longo (long method)
- Classe grande (large class)
- Lista de parâmetros longa (long parameter list)
- Má indentação(Bad Indentation)
O desenvolvedor quando consegue botar em prática a técnica da Refatoração a consequência é a melhora no entendimento do código, o que facilita a manutenção e evita a inclusão de defeitos e esta melhora no entendimento vem da constante alteração do código com objetivo de facilitar a comunicação de motivações, intenções e objetivos por parte do programador.
Refatorações
As refatorações descritas no livro de Martin Fowler utilizam fortemente conceitos de orientação a objeto. Basta observar algumas:
- Extrair Método (Extract Method)
- Mover Método (Move Method)
- Mover Atributo (Move Field’)
- Extrair Classe (Extract Class)
- Encapsular Atributo (Encapsulate Field)
- Renomear Método (Rename Method)
- Subir Método (Pull Up Method)
- Subir Atributo (Pull Up Field)
- Descer Método (Push Down Method)
- Descer Atributo (Push Down Field)
- Extrair Sub-classe (Extract Subclass)
- Extrair Super-classe (Extract Superclass)
É fundamental que o sistema de software possua testes automatizados para realizar Refatoração, sendo assim desta forma, será possível garantir que o comportamento externo não foi alterado.
No livro mais importante sobre Refatoração é Refactoring: Improving the Design of Existing Code de Martin Fowler, onde são explicados os conceitos, motivações e uma série de Refatorações descritas passo a passo.
A programação externa tem a Refatoração como uma de suas práticas.
Exemplo
O código Java abaixo demonstra a aplicação da refatoração para extrair método (Extract Method).
Antes
- /** Salva o produto no banco de dados. */
- public void save() {
- // Verifica propriedades
- if (this.getName() == null) {
- throw new Exception(“Falta nome”);
- }
- if (this.getDescription() == null) {
- throw new Exception(“Falta a descrição”);
- }
- this.getDatabase().save(this);
- }
Depois
- /** Salva o produto no banco de dados. */
- public void save() {
- this.checkProperties();
- this.getDatabase().save(this);
- }
- /** Verifica as propriedades do produto. */
- private void checkProperties() {
- if (this.getName() == null) {
- throw new Exception(“Falta nome do produto.”);
- }
- else if (this.getDescription() == null) {
- throw new Exception(“Falta a descrição do produto.”);
- }
- }