O slideshow foi denunciado.
Utilizamos seu perfil e dados de atividades no LinkedIn para personalizar e exibir anúncios mais relevantes. Altere suas preferências de anúncios quando desejar.

Construindo aplicações mais confiantes - Carolina Karklis

50 visualizações

Publicada em

Carolina Karklis - Software developer, Magnetis

O hype da orientação a objetos passou e com ele precisamos rever algumas práticas.
Até mesmo o codebase mais limpo pode ter mensagens de erro precárias, checagens de tipo de dado em excesso, e uso dispensável de variáveis nulas.
Nessa talk vou refatorar um sistema frágil e mostrar estratégias dentro do paradigma de orientação a objetos para escrever código de forma mais simples e confiante.
No processo, vamos ver padrões de arquitetura de software que podemos usar, como melhorar mensagens para cenários de input inesperado e remover todas as variáveis nulas possíveis do nosso código.

Publicada em: Software
  • Seja o primeiro a comentar

  • Seja a primeira pessoa a gostar disto

Construindo aplicações mais confiantes - Carolina Karklis

  1. 1. Construindo aplicações confiantes Photo by Samuel Zeller on Unsplash
  2. 2. Carolina Karklis @carolkarklis carolina@rubyladies.com.br
  3. 3. magnetis.workable.com
  4. 4. Esse é o livro que me inspirou a falar sobre isso. Eu realmente sou uma entusiasta do Ruby e acredito que o código não tem que trazer dor de cabeça pra gente, e sim ser um meio pra chegarmos aonde queremos. O código deveria passar confiança pra quem mantém ele, mas nem sempre é assim
  5. 5. 🤔 O que não é um código confiante
  6. 6. Code smells 💩 métodos MacGyver 💩 excesso de condicionais 💩 excesso de type checking 💩 nil driven development
  7. 7. Métodos MacGyver
  8. 8. Problema: Métodos longos que fazem muita coisa Solução: Identificar mensagens e papéis, separando o código em partes menores
  9. 9. Photo by Caleb Woods on Unsplash Sistema legado de registro de compras
  10. 10. Em resumo, precisamos de um método para migrar os dados de um sistema legado para o novo
  11. 11. Photo by Annelies Geneyn on Unsplash Primeiro, vamos pensar na história que queremos contar
  12. 12. Photo by Annelies Geneyn on Unsplash 4 partes de um método para contar uma boa história
  13. 13. Photo by Annelies Geneyn on Unsplash 4 partes de um método para contar uma boa história 1. Coletar input
  14. 14. Photo by Annelies Geneyn on Unsplash 4 partes de um método para contar uma boa história 1. Coletar input 2. Realizar o trabalho
  15. 15. Photo by Annelies Geneyn on Unsplash 4 partes de um método para contar uma boa história 1. Coletar input 2. Realizar o trabalho 3. Entregar output
  16. 16. Photo by Annelies Geneyn on Unsplash 4 partes de um método para contar uma boa história 1. Coletar input 2. Realizar o trabalho 3. Entregar output 4. Lidar com falhas
  17. 17. Realizando o trabalho “The foundation of an object oriented system is the message” - Sandi Metz
  18. 18. Mensagens = Ações #parse_legacy_purchase_records
  19. 19. Mensagens = Ações #parse_legacy_purchase_records for #each purchase record we want to:
  20. 20. Mensagens = Ações #parse_legacy_purchase_records for #each purchase record we want to: use #email_address to #get_customer
  21. 21. Mensagens = Ações #parse_legacy_purchase_records for #each purchase record we want to: use #email_address to #get_customer use #product_id to #get_product
  22. 22. Mensagens = Ações #parse_legacy_purchase_records for #each purchase record we want to: use #email_address to #get_customer use #product_id to #get_product #add_purchased_product to the customer record
  23. 23. Mensagens = Ações #parse_legacy_purchase_records for #each purchase record we want to: use #email_address to #get_customer use #product_id to #get_product #add_purchased_product to the customer record #log_successfull_import from the purchase record
  24. 24. Realizando o trabalho “A role is a set of responsibilities” - Rebecca Wirfs-Brock
  25. 25. Messages 💖 Roles Message Role #parse_legacy_purchase_records #each #email_address, #product_id #get_customer #get_product #add_purchased_product #log_successfull_import
  26. 26. Messages 💖 Roles Message Role #parse_legacy_purchase_records data_parser #each #email_address, #product_id #get_customer #get_product #add_purchased_product #log_successfull_import
  27. 27. Messages 💖 Roles Message Role #parse_legacy_purchase_records data_parser #each purchase_list #email_address, #product_id #get_customer #get_product #add_purchased_product #log_successfull_import
  28. 28. Messages 💖 Roles Message Role #parse_legacy_purchase_records data_parser #each purchase_list #email_address, #product_id purchase_record #get_customer #get_product #add_purchased_product #log_successfull_import
  29. 29. Messages 💖 Roles Message Role #parse_legacy_purchase_records data_parser #each purchase_list #email_address, #product_id purchase_record #get_customer customer_list #get_product #add_purchased_product #log_successfull_import
  30. 30. Messages 💖 Roles Message Role #parse_legacy_purchase_records data_parser #each purchase_list #email_address, #product_id purchase_record #get_customer customer_list #get_product product_list #add_purchased_product #log_successfull_import
  31. 31. Messages 💖 Roles Message Role #parse_legacy_purchase_records data_parser #each purchase_list #email_address, #product_id purchase_record #get_customer customer_list #get_product product_list #add_purchased_product customer #log_successfull_import
  32. 32. Messages 💖 Roles Message Role #parse_legacy_purchase_records data_parser #each purchase_list #email_address, #product_id purchase_record #get_customer customer_list #get_product product_list #add_purchased_product customer #log_successfull_import data_importer
  33. 33. def import_legacy_purchase_data(data) purchase_list = data_parser.parse_purchase_records(data) end
  34. 34. def import_legacy_purchase_data(data) purchase_list = data_parser.parse_purchase_records(data) purchase_list.each do |purchase| end end
  35. 35. def import_legacy_purchase_data(data) purchase_list = data_parser.parse_purchase_records(data) purchase_list.each do |purchase| customer = customer_list.get_customer(purchase.email_address) product = product_list.get_product(purchase.product_id) end end
  36. 36. def import_legacy_purchase_data(data) purchase_list = data_parser.parse_purchase_records(data) purchase_list.each do |purchase| customer = customer_list.get_customer(purchase.email_address) product = product_list.get_product(purchase.product_id) customer.add_purchased_product(product) end end
  37. 37. def import_legacy_purchase_data(data) purchase_list = data_parser.parse_purchase_records(data) purchase_list.each do |purchase| customer = customer_list.get_customer(purchase.email_address) product = product_list.get_product(purchase.product_id) customer.add_purchased_product(product) log_successfull_import(purchase_record) end end
  38. 38. Um pouco verboso, mas conta uma história👌
  39. 39. Detalhe Não me preocupei com os colaboradores, e sim com a história e a usabilidade do método
  40. 40. #TODO: Criar a ponte entre os papéis que criamos e objetos de verdade.
  41. 41. Code smells 💩 métodos MacGyver
  42. 42. Excesso de condicionais e type checkings Photo by Javier Allegue Barros on Unsplash
  43. 43. 💣 causa desordem e tira linearidade no código 💣 se torna difícil de testar e manter 💣 embute responsabilidades e conhecimentos desnecessários
  44. 44. A solução é dividida em patterns estratégias específicas: Coagir objetos para que façam o que precisa ser feito Rejeitar valores inesperados de maneira mais eficiente Substituir inputs inaceitáveis por valores válidos
  45. 45. Photo by mauRÍCIO santos on Unsplash Guarde as fronteiras, não as esquinas
  46. 46. Isso é um código confiante. menos type checking menos condicionais
  47. 47. Code smells 💩 métodos MacGyver 💩 excesso de condicionais 💩 excesso de type checking 💩 nil driven development
  48. 48. Nil Driven Development
  49. 49. NoMethodError no Ruby AttributeError no Python NullPointerException no Java TypeError no Javascript
  50. 50. Photo by JOSHUA COLEMAN on Unsplash
  51. 51. Photo by JOSHUA COLEMAN on Unsplash YAGNI You ain’t gonna need it
  52. 52. Converta de maneira implícita ou explícita #to_s #to_str #to_i #to_f
  53. 53. If you know what you want, ask for it
  54. 54. Use conversões do módulo Kernel para outros tipos Array() Integer() Pathname() Hash.[*]
  55. 55. Defina suas próprias conversões para tipos definidos
  56. 56. Não pergunte pelo tipo de objeto, e sim peça a permissão is_a?(Duck) respond_to?(:quack)
  57. 57. Aprenda a usar structs e crie um padrão para seu sistema
  58. 58. Não use nil, não passe nil Utilize o ActiveRecord::NullRelation se precisar retornar um objeto vazio
  59. 59. Joyful Driven Development 🌈
  60. 60. Obrigada! Photo by Samuel Zeller on Unsplash @carolkarklis carolina@rubyladies.com.br

×