Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Code Smells: o que eles dizem sobre seu código?

Elaine Naomi
December 13, 2018

Code Smells: o que eles dizem sobre seu código?

Apresentação RubyConfBR 2018

No mundo do Rails, aprendemos a sempre analisar o nosso código sobre o princípio do DRY e seguimos a estratégia de afastar qualquer lógica das nossas views, manter nossos controllers simples e mover toda a lógica de negócio para nossos models.
E quando a nossa aplicação começa a ficar complexa e de difícil manutenção? Models cada vez maiores e com cenários de testes complexos? O que isso diz sobre a nossa aplicação e sobre a qualidade do código escrito? É hora de começar do zero e reescrever tudo? É hora de mudar de paradigma? É hora de migrar para microsserviços? Calma! Vamos, primeiro, identificar os problemas de design da base de código atual.
Nessa talk, vamos conhecer code smells que nos auxiliam na refatoração e na medição da qualidade do nosso código, discutindo o impacto das decisões de design na evolução das aplicações, na entrega de funcionalidades, no processo de desenvolvimento e na comunicação e interação entre as pessoas da equipe.

Elaine Naomi

December 13, 2018
Tweet

More Decks by Elaine Naomi

Other Decks in Programming

Transcript

  1. Elaine Naomi Watanabe Desenvolvedora de Software (Plataformatec) Mestre em Ciência

    da Computação (USP) twitter.com/elaine_nw speakerdeck.com/elainenaomi
  2. 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?
  3. Como os objetos estão organizados? Quais métodos e classes foram

    criados? O código é fácil de ser reutilizado?
  4. Tamanho da base de código Tempo de entregas Nota: gráfico

    ilustrativo, mas baseado em fatos reais
  5. 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/
  6. Por que refatorar? Código fácil de ler Código fácil de

    entender Código fácil de manter Código limpo
  7. Dívida Técnica Custo da mudança Tempo Fonte: How to Monetize

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

    How to Monetize Application Technical Debt, Gartner, 2011
  9. 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.
  10. Como medir a necessidade de refatoração? Quantidade de código duplicado

    Cobertura de testes Desempenho da suíte de testes Complexidade ciclomática
  11. 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
  12. Dificuldade em dizer o que o método faz, Excesso de

    ifs ou case statements Extrair método Long Method
  13. 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
  14. Mesma alteração em vários arquivos, Buscas globais para toda alteração

    Extrair método, Extrair classe, Substituir condicional por polimorfismo Shotgun Surgery
  15. 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
  16. 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
  17. 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
  18. 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
  19. # ... def charge(total) if credit_card.active? payment_gateway.charge(total) end end def

    active? status == 3 end mais segundos de vida economizados! o/
  20. # Public: Integer number of seconds to wait # before

    connection timeout. CONNECTION_TIMEOUT = 60
  21. # 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/
  22. Temporary Field Message Chains Middle Man Alternative Classes with Different

    Interfaces Incomplete Library Class Data Class Refused Bequest Long Parameter List
  23. 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
  24. 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
  25. 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
  26. 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)
  27. E nem sempre a ideia é sair extraindo classes! Pessoa

    Pessoa Física Pessoa Collapse hierarchy