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

[2020-12-04] RubySummitBR - Desmacarronando código com dry-RB

[2020-12-04] RubySummitBR - Desmacarronando código com dry-RB

Já trabalhou com aquele código legado, super macarronado, que é pior que aqueles postes de fio que estão prestes a dar vários curtos? Pois bem, nessa palestra apresentarei como saímos de um código tão espaguete que era quase impossível de mexer para uma nova versão em que conseguíamos incluir funcionalidades em apenas algumas horas. Usando o dry-transactions, um componente do dry-rb, melhoramos nosso código (sem remover a complexidade), passamos a ter mais domínio do contexto e, de quebra, acabamos mais motivados

Camila Campos

December 04, 2020
Tweet

More Decks by Camila Campos

Other Decks in Programming

Transcript

  1. Desmacarronando código com dry-rb

  2. @camposmilaa Camila Campos Meu propósito de vida é influenciar para

    reduzir desigualdades sócio-culturais dentro de tecnologia, através da educação e do bom humor.
  3. @camposmilaa Software Engineer @ SumUp Rails Girls São Paulo &

    Women Dev Summit & Ruby Summit BR Camila Campos
  4. sumup.onl/secandidate

  5. Desmacarronando código com dry-rb

  6. Agenda Contexto Time, Projeto & Pessoas Entrega Primeira versão do

    projeto Desmacarronação Como foi a refatoração e o uso do DRY-RB 1. 2. 3. Conclusões O que aprendemos com tudo isso 4.
  7. Contexto time 1.1.

  8. Estou na SumUp há 3 meses..

  9. ... mas esse causo se passa na ex-firma

  10. Time de Crédito Auto, desde Set/2019

  11. Contexto projeto 1.2.

  12. Final de Setembro/2019...

  13. Decisões manuais (feitas por analistas de crédito)

  14. Decisões manuais (feitas por analistas de crédito) Reprovações automáticas (cerca

    de 10% das análises)
  15. Decisões manuais (feitas por analistas de crédito) Reprovações automáticas (cerca

    de 10% das análises) Codebase de 3 anos (decisões manuais e reprovação automática)
  16. Implementar decisões automáticas

  17. Objetivo 10% de rejeições 75% de decisões

  18. Objetivo 10% de rejeições 75% de decisões Grande aposta do

    business
  19. Objetivo 10% de rejeições 75% de decisões Entrega até começo

    de outubro (risos)
  20. Começo de Outubro/2019...

  21. Decisões manuais (feitas por analistas de crédito) Reprovações automáticas (cerca

    de 10% das análises) Codebase de 3 anos (decisões manuais e reprovação automática)
  22. Atrasos (prazo estourado, complicações e muito chão) Decisões manuais (feitas

    por analistas de crédito) Reprovações automáticas (cerca de 10% das análises) Codebase de 3 anos (decisões manuais e reprovação automática)
  23. Contexto emocional 1.3.

  24. Time desmotivado • Atrasos e Complicações

  25. Time desmotivado • Atrasos e Complicações • Outras demandas

  26. • Atrasos e Complicações • Outras demandas • Pressão externa

    e interna Time desmotivado
  27. Time desmotivado • Atrasos e Complicações • Outras demandas •

    Pressão externa e interna • Demais coisas pessoais
  28. Entrega da V1 2.

  29. Ihuuuulll!

  30. Começo de Novembro/2019...

  31. Habemus macarronada

  32. 15 a 20% de decisões automáticas (bem longe da meta)

  33. Esboço do fluxo original Durante esse período todo...

  34. Alinhamento com stakeholders Esboço do fluxo original Durante esse período

    todo...
  35. Alinhamento com stakeholders Esboço do fluxo original Combinado com PM

    e liderança Durante esse período todo...
  36. Alinhamento com stakeholders Derteminação do time Esboço do fluxo original

    Combinado com PM e liderança Durante esse período todo...
  37. Hora de arrumar a casa

  38. adeus pressão

  39. Refatoração da macarronada 3.1.

  40. 1. Desenho completo do fluxo original

  41. None
  42. 2. Problemas & Insights

  43. None
  44. None
  45. None
  46. None
  47. None
  48. essa era a macarronada

  49. 3. Definição de um novo fluxo

  50. None
  51. None
  52. None
  53. None
  54. None
  55. None
  56. None
  57. Esses desenhos são uma simplificação dos fluxos (desenho original &

    refactor)
  58. None
  59. Agregação e transformação de dados Achar entidade A Achar entidade

    B Consultar serviço 2 Transformar dados Consultar serviço 3 Calcular valores X ... Consultar serviço 4 Calcular valores Y
  60. 4. Taca-le pau nesse motorzinho

  61. Taca-le pau Prova de Conceito Simples, de um a dois

    dias
  62. Quebra de histórias Pequenos entregáveis, a maioria testáveis Taca-le pau

    Prova de Conceito Simples, de um a dois dias
  63. Quebra de histórias Pequenos entregáveis, a maioria testáveis Mão na

    massa 3 meses sem pressão e com motivação Taca-le pau Prova de Conceito Simples, de um a dois dias
  64. Quebra de histórias Pequenos entregáveis, a maioria testáveis Mão na

    massa 3 meses sem pressão e com motivação Taca-le pau Prova de Conceito Simples, de um a dois dias
  65. Quebra de histórias Pequenos entregáveis, a maioria testáveis Mão na

    massa 3 meses sem pressão e com motivação Entrega do refactor Fluxos simultâneos, comp. de resultados e virada de chave Taca-le pau Prova de Conceito Simples, de um a dois dias
  66. None
  67. None
  68. None
  69. None
  70. None
  71. Implementação com dry-rb 3.2.

  72. https://dry-rb.org/

  73. None
  74. dry-transaction

  75. https://dry-rb.org/gems/dry-transaction/0.13/ Fornece uma maneira simples de definir uma transação de

    negócio através de vários passos.
  76. Agregar dados de crédito Achar entidade A Achar entidade B

    Consultar serviço 2 Consultar serviço 3 Calcular valores X Consultar serviço 4
  77. Agregar dados de crédito Achar entidade A Achar entidade B

    Consultar serviço 2 Consultar serviço 3 Calcular valores X Consultar serviço 4 transaction
  78. Agregar dados de crédito Achar entidade A Achar entidade B

    Consultar serviço 2 Consultar serviço 3 Calcular valores X Consultar serviço 4 step/operation transaction
  79. Achar entidade A Achar entidade B Agregar dados de crédito

    saída step 1 = entrada step 2 entrada trans. = entrada step 1 saída step. = saída trans.
  80. na prática

  81. require "dry/transaction" class AggregateData include Dry::Transaction step :find_entity_a step :consult_service_2

    private def find_entity_a(a_id:) # returns Success(credit_data: data) # or Failure(error) end def consult_service_2(credit_data:);end end
  82. require "dry/transaction" class AggregateData include Dry::Transaction step :find_entity_a step :consult_service_2

    private def find_entity_a(a_id:) # returns Success(credit_data: data) # or Failure(error) end def consult_service_2(credit_data:);end end
  83. require "dry/transaction" class AggregateData include Dry::Transaction step :find_entity_a step :consult_service_2

    private def find_entity_a(a_id:) # returns Success(credit_data: data) # or Failure(error) end def consult_service_2(credit_data:);end end
  84. require "dry/transaction" class AggregateData include Dry::Transaction step :find_entity_a step :consult_service_2

    private def find_entity_a(a_id:) # returns Success(credit_data: data) # or Failure(error) end def consult_service_2(credit_data:);end end
  85. require "dry/transaction" class AggregateData include Dry::Transaction step :find_entity_a step :consult_service_2

    private def find_entity_a(a_id:) # returns Success(credit_data: data) # or Failure(error) end def consult_service_2(credit_data:);end end
  86. class AggregateData include Dry::Transaction step :find_entity_a step :consult_service_2 private def

    find_entity_a(a_id:) entity = repository.find(a_id) return Failure(message: "A not found") unless entity data = build_data_aggregate_with(entity) Success(credit_data: data) end def consult_service_2(credit_data:); end end
  87. class AggregateData include Dry::Transaction step :find_entity_a step :consult_service_2 step :some_step03

    step :some_step04 step :some_step05 step :some_step06 step :some_step07 step :some_step08 step :some_step09 step :some_step10 step :some_step11 step :some_step12 step :some_step13 step :some_step14 step :some_step15 step :some_step16 step :some_step17 step :some_step18 step :some_step19 step :some_step20 step :some_step21 # .... private def find_entity_a(a_id:); end # .... end
  88. class AggregateData include Dry::Transaction step :find_entity_a private def find_entity_a(a_id:) entity

    = repository.find(a_id) return Failure(message: "A not found") unless entity data = build_data_aggregate_with(entity) Success(credit_data: data) end end
  89. class FindEntityA include Dry::Monads[:result] def call(a_id:, **args) entity = RepoInstance.new.find(a_id)

    return Failure(message: "A not found") unless entity data = build_data_aggregate_with(entity) Success(credit_data: data) end end
  90. class FindEntityA include Dry::Monads[:result] def call(a_id:, **args) entity = RepoInstance.new.find(a_id)

    return Failure(message: "A not found") unless entity data = build_data_aggregate_with(entity) Success(credit_data: data) end end
  91. class AggregateData include Dry::Transaction def initialize steps = { find_entity_a:

    FindEntityA.new } super(**steps) end step :find_entity_a end
  92. Um pouco de mágica Facilitamos testes e adição de novas

    operações
  93. ufa, cabô o refactor

  94. Conclusões vitórias e aprendizados 4.

  95. Felicidade e motivação

  96. Velocidade de entrega pós refactor

  97. Antes: 1 - 2 semanas Depois: 2 - 48 horas

  98. Percepções para evolução futura

  99. O dry-rb foi uma ferramenta

  100. alinhamento, priorização, implementação Processo do refactor

  101. É uma das coisas que mais tenho orgulho na minha

    carreira. Obrigada ex-time!
  102. CREDITS: This presentation template was created by Slidesgo, including icon

    by Flaticon, and infographics & images from Freepik @camposmilaa Valeu! bit.ly/camis-rubysummit2020
  103. Useful stuff