Slide 1

Slide 1 text

code smells: o que eles dizem sobre seu código?

Slide 2

Slide 2 text

hello

Slide 3

Slide 3 text

Elaine Naomi Watanabe Desenvolvedora de Software (Plataformatec) Mestre em Ciência da Computação (USP) twitter.com/elaine_nw speakerdeck.com/elainenaomi

Slide 4

Slide 4 text

http://careers.plataformatec.com.br temos vagas o/

Slide 5

Slide 5 text

http://careers.plataformatec.com.br + sorteios!!

Slide 6

Slide 6 text

qual a importância da qualidade do seu código como reconhecer os sinais de problemas na base de código como lidar com dívida técnica e refatorar nossas aplicações O que vamos ver?

Slide 7

Slide 7 text

qualidade de software

Slide 8

Slide 8 text

Software confiável Funcionamento correto (sem bugs) Entrega do valor esperado O que queremos?

Slide 9

Slide 9 text

e como garantimos a qualidade?

Slide 10

Slide 10 text

Testes automatizados Revisão de código Testes em QA O que fazemos?

Slide 11

Slide 11 text

Testes automatizados Revisão de código Testes de aceitação O que fazemos?

Slide 12

Slide 12 text

e em relação ao código escrito?

Slide 13

Slide 13 text

o que precisamos considerar?

Slide 14

Slide 14 text

Como os objetos estão organizados? Quais métodos e classes foram criados? O código é fácil de ser reutilizado?

Slide 15

Slide 15 text

"o que importa é código funcionando"

Slide 16

Slide 16 text

Tamanho da base de código Tempo de entregas Nota: gráfico ilustrativo, mas baseado em fatos reais

Slide 17

Slide 17 text

"Esse código é difícil de entender"

Slide 18

Slide 18 text

"Joga isso fora e começa do zero"

Slide 19

Slide 19 text

No content

Slide 20

Slide 20 text

Quando reescrever um sistema? Uso de tecnologia desatualizada Contratação de pessoas está difícil Existência de tecnologias mais vantajosas Fonte: http://blog.plataformatec.com.br/2016/07/key-points-to-consider-when-doing-a-software-rewrite/

Slide 21

Slide 21 text

No content

Slide 22

Slide 22 text

e temos outros caminhos?

Slide 23

Slide 23 text

que tal refatorar o código?

Slide 24

Slide 24 text

Refatoração processo de melhorar o design do código existente, alterando o software sem alterar o seu comportamento

Slide 25

Slide 25 text

Por que refatorar? Código fácil de ler Código fácil de entender Código fácil de manter Código limpo

Slide 26

Slide 26 text

precisamos mesmo refatorar?

Slide 27

Slide 27 text

Dívida Técnica Custo da mudança Tempo Fonte: How to Monetize Application Technical Debt, Gartner, 2011

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

Dívida Técnica Valor de negócio Custo da mudança Tempo Fonte: How to Monetize Application Technical Debt, Gartner, 2011

Slide 30

Slide 30 text

No content

Slide 31

Slide 31 text

e como evitar isso?

Slide 32

Slide 32 text

Custo da mudança Tempo dívida técnica refatoração caso ótimo Fonte: An Empirical Model of Technical Debt and Interest, MTD' 11, Ariadni Nugroho et al.

Slide 33

Slide 33 text

Como medir a necessidade de refatoração? Quantidade de código duplicado Cobertura de testes Desempenho da suíte de testes Complexidade ciclomática

Slide 34

Slide 34 text

def total_compra(valor, epoca) total = 0 total += 0.1 if valor < 100 total += 0.5 if epoca.pre_black_friday? total end Complexidade ciclomática: 4

Slide 35

Slide 35 text

e onde entram os code smells?

Slide 36

Slide 36 text

Code smells Sintomas no código que indicam possíveis problemas de design em sistemas orientados a objeto

Slide 37

Slide 37 text

Code smells Indícios de que o código precisa ser refatorado

Slide 38

Slide 38 text

Martin Fowler e Kent Beck listam 22 code smells e sugerem como refatorá-los

Slide 39

Slide 39 text

no mundo do Ruby...

Slide 40

Slide 40 text

No content

Slide 41

Slide 41 text

exemplos de code smells

Slide 42

Slide 42 text

Duplicated Code Código duplicado Extrair método, Extrair classe, Substituir condicional por polimorfismo

Slide 43

Slide 43 text

Regra de negócio duplicada != Texto duplicado

Slide 44

Slide 44 text

Dificuldade em dizer o que o método faz, Excesso de ifs ou case statements Extrair método Long Method

Slide 45

Slide 45 text

Large Class Muitos métodos, God Classes, Dificuldade em dizer o que a classe faz, Excesso de concerns Extrair método, Extrair classe, Substituir condicional por polimorfismo

Slide 46

Slide 46 text

Mesma alteração em vários arquivos, Buscas globais para toda alteração Extrair método, Extrair classe, Substituir condicional por polimorfismo Shotgun Surgery

Slide 47

Slide 47 text

Acesso mais a dados de outro objeto, Violação do princípio Tell, don't ask Extrair método, Mover método, Internalizar classe Feature Envy

Slide 48

Slide 48 text

class Subscription def charge(user) if user.has_credit_card? user.charge(total) else false end end end Violação do princípio Tell, don't ask Subscription não confia na classe User

Slide 49

Slide 49 text

Conhecer/alterar detalhes internos de outra classe Extrair método Inappropriate Intimacy

Slide 50

Slide 50 text

class Subscription def charge(user) if user.has_credit_card? && user.credit_card.status == 3 user.charge(total) user.current_installment.paid! end end end

Slide 51

Slide 51 text

class Subscription def charge(user) if user.has_credit_card? && user.credit_card.status == 3 user.charge(total) user.current_installment.paid! end end end Subscription sabe demais sobre User, Credit Card e Installment

Slide 52

Slide 52 text

Classe alterada constantemente Mudanças não relacionadas Mover método, Extrair classe, Uso de Form Object Divergent Change

Slide 53

Slide 53 text

Vários comentários explicando o funcionamento do método Extrair variáveis explicativas, Extrair métodos, Renomear métodos Comments

Slide 54

Slide 54 text

# ... def charge(a) if credit_card.status == 3 payment_gateway.charge(a) end end

Slide 55

Slide 55 text

# ... def charge(total) if credit_card.status == 3 payment_gateway.charge(total) end end segundos de vida economizados! o/

Slide 56

Slide 56 text

# ... def charge(total) if credit_card.status == 3 payment_gateway.charge(total) end end

Slide 57

Slide 57 text

# ... def charge(total) if credit_card.active? payment_gateway.charge(total) end end def active? status == 3 end mais segundos de vida economizados! o/

Slide 58

Slide 58 text

comentário != documentação

Slide 59

Slide 59 text

SECONDS_FOR_CONNECTION_TIMEOUT_IN_INTEGER = 60

Slide 60

Slide 60 text

# Public: Integer number of seconds to wait # before connection timeout. CONNECTION_TIMEOUT = 60

Slide 61

Slide 61 text

# Public: A summary of how much some user has consumed in a certain plan. # # Examples # plan_consumption_summary(contracted_plan) # # => '2.44% (500 MB of 20 GB)' # # Returns a String. def plan_consumption_summary(contracted_plan) total_contracted = contracted_plan.plan_storage_limit total_consumed = contracted_plan.total_consumed # ... Fonte: http://blog.plataformatec.com.br/2018/06/the-anatomy-of-code-documentation/

Slide 62

Slide 62 text

Data Clumps Primitive Obsession Switch Statements Parallel Inheritance Hierarchies Lazy Class Speculative Generality Outros code smells

Slide 63

Slide 63 text

Temporary Field Message Chains Middle Man Alternative Classes with Different Interfaces Incomplete Library Class Data Class Refused Bequest Long Parameter List

Slide 64

Slide 64 text

e como evitar os code smells? reduzir

Slide 65

Slide 65 text

design de código

Slide 66

Slide 66 text

Objetos Interfaces públicas e privadas Herança vs Composição Polimorfismo

Slide 67

Slide 67 text

Polimorfismo ter uma interface única de acesso para diferentes classes/objetos

Slide 68

Slide 68 text

class FinancialReport def generate(account, file_format) case file_format when :csv file = FormatCSV.generate(account.transactions) when :pdf file = PDFGenerator.print(account.transactions) end Mailer.send(account.email, file) end end

Slide 69

Slide 69 text

class FinancialReport def generate(account, file_format) case file_format when :csv file = FormatCSV.generate(account.transactions) when :pdf file = PDFGenerator.print(account.transactions) end Mailer.send(account.email, file) end end

Slide 70

Slide 70 text

class FinancialReport def generate(account, file_format) case file_format when :csv file = FormatCSV.generate(account.transactions) when :pdf file = PDFGenerator.print(account.transactions) when :xls file = FormatXLSGenerator.run(account.transactions) end Mailer.send(account.email, file) end end

Slide 71

Slide 71 text

class FinancialReport def generate(account, file_creator) file = file_creator.create(account.transactions) Mailer.send(account.email, file) end end

Slide 72

Slide 72 text

class FileCreatorPDF def create(items) PDF.print(items) end end class CSVGenerator def create(items) FormatCSV.generate(items) end end

Slide 73

Slide 73 text

class FileCreatorPDF def create(items) PDF.print(items) end end class CSVGenerator def create(items) FormatCSV.generate(items) end end

Slide 74

Slide 74 text

class FinancialReport def generate(account, file_creator) file = file_creator.create(account.transactions) Mailer.send(account.email, file) end end FinancialReport.new.generate(account, FileCreatorPDF.new) FinancialReport.new.generate(account, CSVGenerator.new)

Slide 75

Slide 75 text

class FinancialReport def generate(account, file_creator) file = file_creator.create(account.transactions) Mailer.send(account.email, file) end end FinancialReport.new.generate(account, FileCreatorXLS.new)

Slide 76

Slide 76 text

Coesão Encapsulamento Acoplamento Abstração de Tipos

Slide 77

Slide 77 text

E nem sempre a ideia é sair extraindo classes! Pessoa Pessoa Física Pessoa Collapse hierarchy

Slide 78

Slide 78 text

Ter boa cobertura de testes é essencial para garantir a evolução do seu sistema

Slide 79

Slide 79 text

refatoração != revolução

Slide 80

Slide 80 text

e aí, o que code smells dizem sobre o nosso código?

Slide 81

Slide 81 text

Apontam possíveis problemas de design Alertam sobre redução da qualidade Indicam possível impacto no negócio

Slide 82

Slide 82 text

No content

Slide 83

Slide 83 text

TL;DR;

Slide 84

Slide 84 text

TL;DR: Qualidade de código Code smells Refatoração

Slide 85

Slide 85 text

No content

Slide 86

Slide 86 text

No content

Slide 87

Slide 87 text

esses conceitos nos ajudam a criar aplicações mais saudáveis

Slide 88

Slide 88 text

mas não é para refatorar só porque existe um code smell

Slide 89

Slide 89 text

ou tratar todo code smell como um falso positivo

Slide 90

Slide 90 text

precisamos olhar para o código que deixamos como legado

Slide 91

Slide 91 text

converse com seu time sobre a importância da qualidade do código

Slide 92

Slide 92 text

converse com seu time sobre a importância da qualidade do código + qualidade de software

Slide 93

Slide 93 text

analisem juntos os trade-offs

Slide 94

Slide 94 text

cuidado com big design up front e overengineering

Slide 95

Slide 95 text

e não esqueçam:

Slide 96

Slide 96 text

codar é um processo de comunicação

Slide 97

Slide 97 text

No content

Slide 98

Slide 98 text

Mais sobre qualidade de software? Design de código, SOLID Padrões de projeto TDD, DDD, Agile

Slide 99

Slide 99 text

minhas referências

Slide 100

Slide 100 text

No content

Slide 101

Slide 101 text

No content

Slide 102

Slide 102 text

guidelines.plataformatec.com.br thoughtbot.com/upcase/clean-code refactoring.guru Mais referências:

Slide 103

Slide 103 text

No content

Slide 104

Slide 104 text

No content

Slide 105

Slide 105 text

Até a próxima!

Slide 106

Slide 106 text

obrigada speakerdeck.com/elainenaomi