Você está na página 1de 78

Engenharia de Software Moderna

Cap. 9 - Refactoring

Prof. Marco Tulio Valente


https://engsoftmoderna.info, @engsoftmoderna

Licença CC-BY; permite copiar, distribuir, adaptar etc; porém, créditos devem ser dados ao autor dos
slides 1
Relembrando Cap. 1 (Introdução)

2
Manutenção de Software
● Preventiva: bugs "latentes"
● Corretiva: bugs reportados por usuários
● Adaptativa: customizações, novas versões de LP/SO
● Evolutiva: novas funcionalidades
● Refactoring: melhorias no código ou design

3
Antes de começar com refactoring …
Leis de Lehman

4
Leis de Lehman
● Leis empíricas sobre evolução de software
● Propostas por Meir Lehman, nas décadas 70-80

5
Resumo das Leis de Lehman
● Sistemas devem ser sempre mantidos para serem úteis
● Mas manutenções aumentam a complexidade e
deterioram a qualidade do código
● A não ser que um trabalho seja realizado para evitar isso

Modernamente, este trabalho ganhou


o nome de refactoring
6
Refactoring
● Transformações de código que melhoram a
manutenibilidade de um sistema mas sem afetar o seu
funcionamento externo

7
Refactoring
● Conceito tornou-se bastante popular ...

1999 2000 2018 8


Refactoring
● Refactoring = refatoração
● Não vamos traduzir… termo em inglês é muito usado

9
Eu não sou um excelente programador, mas um bom
programador com excelentes hábitos – Kent Beck

10
Catálogo de Refactorings
● Extração de Métodos
● Inline de Métodos
● Movimentação de Métodos
● Extração de Classes
● Renomeação
● etc
11
Extração de Métodos

12
Extração de Métodos

13
Um exemplo real ...

14
Antes

15
Depois

16
Canivete-suíço dos
refactorings

Danilo Silva, Nikolaos Tsantalis, Marco Tulio Valente.


Why We Refactor? Confessions of GitHub Contributors.
FSE 2016.

17
Inline de Métodos (contrário de extração)

18
Antes

19
Depois

20
Movimentação de Métodos

21
22
Casos particulares de movimentação
(ao longo de uma hierarquia de classes)

23
Pull Up Method

24
Push Down Method

25
Extração de Classes

26
27
Renomeação
(variáveis, parâmetros, métodos, classes, exceções,
etc)

28
Dar bons nomes a variáveis é um dos
problemas mais difíceis em programação!

29
Renomação é o refactoring mais popular

Murphy-Hill, et al. How We Refactor, and How We Know It. IEEE TSE 2012.

30
Prática de Refactorings

31
Refactorings dependem de testes
Desenvolvedores evitam refatorações em sistemas
sem testes. Em vez disso, eles reduzem as modificações
àquelas necessárias para implementar novas
funcionalidades ou corrigir bugs. Assim, a complexidade
vai se acumulando e erros de projeto não são corrigidos
-- John Ousterhout

32
Quando refatorar?
1. Refactorings oportunistas
2. Refactorings planejados

33
Refactorings Oportunistas
● Realizados no meio de uma outra tarefa de programação
● Tipo de refactoring mais comum
● Para cada mudança que tiver que realizar em um
sistema, primeiro torne-a fácil (aviso: isso pode ser difícil),
então realize a mudança facilmente -- Kent Beck

34
Refactorings Planejados
● Correção de um problema de design mais complexo
● Sessão apenas para realização de refactorings

35
Refactorings Automatizados
(realizados com auxílio de uma IDE)

36
37
38
Observação: O único rename
analisado foi de pacote

Danilo Silva, Nikolaos Tsantalis, Marco Tulio Valente. Why We Refactor?


Confessions of GitHub Contributors. FSE 2016.

39
40
Code Smells

41
Code (ou Bad) Smells
● Indicadores de código de baixa qualidade
● Difícil de manter, entender, modificar ou testar
● Portanto, candidato a refatoração

42
Catálogo de Code Smells
● Código Duplicado ● Obsessão por Tipos
● Métodos Longos Primitivos
● Classes Grandes ● Objetos Mutáveis
● Feature Envy ● Classes de Dados
● Métodos com Muitos ● Comentários
Parâmetros
● Variáveis Globais

43
Código Duplicado

44
Código Duplicado
● Dificulta a manutenção
● Portanto, código candidato a refatoração

45
Aiko Yamashita, Leon Moonen. Do
developers care about code smells? An
exploratory survey. WCRE 2013.

46
Código Duplicado ⇒ Clones

47
Clone Tipo 1 (comentários e espaços)
Código Original

48
Clone Tipo 2 (tipo 1 + nomes diferentes)
Código Original

49
Clone Tipo 3 (tipo 2 + mudanças em comandos)
Código Original

50
Clone Tipo 4 (algoritmos diferentes, mas equivalentes)
Código Original

51
Feature Envy

52
Feature Envy
● Método que "inveja" dados e métodos de outra classe
● Usa mais métodos e dados dessa outra classe
● Logo, é um candidato a ser movido para ela

53
54
Variáveis Globais

55
Variáveis Globais
● Acoplamento ruim
● Dificulta o entendimento de um método

Para entender o que f retorna, precisamos conhecer o valor de g


Esse valor pode variar entre chamadas de f, etc
56
Obsessão por Tipos Primitivos

57
Obsessão por Tipos Primitivos
● CEP, Moeda, Data, Hora, Cor, Email, etc não devem ser
de tipos primitivos
● Mas sim de um tipo próprio, com alguns métodos
● Por exemplo, métodos para validação de valores

58
Objetos Mutáveis

59
Objetos Mutáveis vs Imutáveis
● Mutáveis: estado pode mudar
● Imutáveis: uma vez criados, estado não muda

60
Objetos Imutáveis: Strings em Java

Hello World

HELLO WORLD

61
Por que objetos imutáveis são "bons"?
● Dão segurança a quem criou o objeto
● Pode-se passar o objeto para outros métodos e ter
certeza de que eles não vão alterar o seu estado

62
Como interpretar esse code smell
● Sempre que possível, implemente objetos imutáveis
● Principalmente, objetos mais simples (CEP, Data, Hora, etc)
● Mas, por outro lado, em linguagens imperativas é natural
ter um bom número de objetos mutáveis.

63
Comentários

64
A ideia é a seguinte:

"não comente código ruim, reescreva-o"


-- B. Kerninghan & P. J. Plauger

65
66
67
Comentários "Ruído" (nada acrescentam …)

// this function sends an email


void sendEmail() {
...
}

// this class holds data for an employee


public class Employee {
...
}

68
Mais um exemplo de comentários "ruído"
Comentários apenas repetem o
que já está bem claro no código

Fonte: A Philosophy of Software Design (capítulo 13)

69
Evidentemente, nem todo comentário é um
code smell ...

70
Quando é útil comentar?
● Código complexo por natureza
// format matched kk:mm:ss EEE, MMM dd, yyy
Pattern timePattern = Pattern.compile("\\d*:\\d*:\\d* \\w*, \\w*, \\d*, \\d*");

71
Quando é útil comentar?
● Documentação de APIs
/**
* Registers the text to display in a tool tip. The text
* displays when the cursor lingers over the component.
*
* @param text the string to display. If the text is null,
* the tool tip is turned off for this component.
*/
public void setToolTipText(String text) {

72
Antes de terminar...

Débito Técnico

73
Débito Técnico

● Metáfora para explicar a importância de boas práticas e


princípios de Engenharia de Software
● Proposto por Ward Cunningham (1992)
● Soluções não-ótimas de design que dificultam a
manutenção e evolução de um sistema

74
75
Projeto no qual TD Projeto no qual TD foi
não foi pago sendo pago

Speed = velocidade de implementação de novas funcionalidades


76
Exemplos de Débito Técnico
● Ausência de testes
● Ausência de builds automatizado
● Problemas arquiteturais
● Alto acoplamento e baixa coesão
● Code smells
● Ausência completa de documentação
● Código que não segue layout pré-definido
77
Fim

78

Você também pode gostar