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.
13/12/2018
6. 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?
20. 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/
44. Dificuldade em dizer o que o método faz,
Excesso de ifs ou case statements
Extrair método
Long Method
45. 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
46. Mesma alteração em vários arquivos,
Buscas globais para toda alteração
Extrair método, Extrair classe,
Substituir condicional por polimorfismo
Shotgun Surgery
47. 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
48. 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
50. 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
51. 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
57. # ...
def charge(total)
if credit_card.active?
payment_gateway.charge(total)
end
end
def active?
status == 3
end
mais segundos de vida economizados!
o/
60. # Public: Integer number of seconds to wait
# before connection timeout.
CONNECTION_TIMEOUT = 60
61. # 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/
63. Temporary Field
Message Chains
Middle Man
Alternative Classes with Different Interfaces
Incomplete Library Class
Data Class
Refused Bequest
Long Parameter List
68. 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
69. 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
70. 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
74. 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)
75. 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)