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

B/CDD - RubyConf BR - 2022

B/CDD - RubyConf BR - 2022

https://bit.ly/aprendabcdd

Resumo
======
B/CDD é um processo de desenvolvimento que visa conciliar velocidade, qualidade e pragmatismo no desenvolvimento de software. Eu o criei ao longo dos últimos anos e o mesmo se provou eficaz em diferentes empresas, times e codebases Ruby/Rails.

A talk apresenta seus benefícios, fundamentos e foca em demonstrar sua aplicação de forma prática.

Descrição
========

O Ruby on Rails é um framework altamente produtivo e sempre foi escolhido como uma ferramenta para promover entregas, mas é muito comum ouvir relatos do quão difícil é escalar o desenvolvimento em um codebase na qual a complexidade ficou alta por conta da evolução das regras de negócio.

Todo negócio tem valor ao gerar valor para quem faz uso dele, e para isso precisa se adaptar continuamente para gerar cada vez mais valor para permanecer relevante e vivo.

Essa capacidade de adaptação está intrisicamente ligada a sua capacidade de entrega. Logo, conciliar velocidade com qualidade é determinante para obter os melhores resultados possíveis.

Eu criei o u-case como um meio de acomodar melhor as regras de negócio de um codebase Ruby / Rails, ou seja, eu o criei para potencializar o desenvolvimento usando Ruby on Rails. A partir de seu uso em diferentes codebases com diferente complexidades e diferentes dinâmicas de time e empresa, vi emergir um padrão de desenvolvimento que facilita a implementação e manutenção de funcionalidades. Um padrão capaz de conciliar velocidade com qualidade e que se adapta bem aos diferentes momentos que toda empresa passa. Esse padrão que recebeu o nome de B/CDD.

Rodrigo Serradura

September 09, 2022
Tweet

More Decks by Rodrigo Serradura

Other Decks in Programming

Transcript

  1. Custo? • Custo para escrever código novo • Custo para

    promover mudanças em código existente • Custo para entender código existente • Custo da espera pelo código
  2. Racional até aqui Custo do software = Investimento necessário para

    promover mudanças (manter o sistema) Acoplamento = Propagação de mudanças Alto acoplamento = Alto custo para manter o software Baixo custo para manter o software = Baixo Acoplamento
  3. Racional até aqui Desacoplar código = Reduzir o custo da

    mudança Reduzir o custo da mudança = Engenharia de software Engenharia de software = Qualidade Qualidade = Desacoplar código
  4. 02 directories, 06 files app ├── controllers │ ├── application_controller.rb

    │ ├── todos_controller.rb │ └── users_controller.rb └── models ├── application_record.rb ├── todo.rb └── user.rb v00
  5. 04 directories, 12 files app ├── controllers │ ├── application_controller.rb

    │ ├── todos_controller.rb │ └── users_controller.rb ├── models │ ├── application_record.rb │ ├── todo.rb │ └── user.rb ├── serializers │ ├── application_serializer.rb │ ├── todo_serializer.rb │ └── user_serializer.rb └── services ├── application_service.rb ├── todo_service.rb └── user_service.rb v01
  6. 04 directories, 17 files app ├── controllers │ ├── application_controller.rb

    │ ├── todos_controller.rb │ └── users_controller.rb ├── models │ ├── application_record.rb │ ├── todo.rb │ └── user.rb ├── serializers │ ├── application_serializer.rb │ ├── todo_serializer.rb │ └── user_serializer.rb └── services ├── application_service.rb ├── complete_todo_service.rb ├── create_todo_service.rb ├── create_user_service.rb ├── destroy_todo_service.rb ├── find_todo_service.rb ├── find_todos_service.rb └── uncomplete_todo_service.rb v02
  7. 06 directories, 17 files app ├── controllers │ ├── application_controller.rb

    │ ├── todos_controller.rb │ └── users_controller.rb ├── models │ ├── application_record.rb │ ├── todo.rb │ └── user.rb ├── serializers │ ├── application_serializer.rb │ ├── todo_serializer.rb │ └── user_serializer.rb └── services ├── application_service.rb ├── todo │ ├── complete_service.rb │ ├── create_service.rb │ ├── destroy_service.rb │ ├── find_all_service.rb │ ├── find_service.rb │ └── uncomplete_service.rb └── user └── create_service.rb v03
  8. 09 directories, 22 files app ├── controllers │ ├── application_controller.rb

    │ ├── todos_controller.rb │ └── users_controller.rb ├── enums │ ├── todo_statuses_enum.rb │ └── user_roles_enum.rb ├── models │ ├── application_record.rb │ ├── todo.rb │ └── user.rb ├── permitted_params │ ├── todo_permitted_params.rb │ └── user_permitted_params.rb ├── serializers │ ├── application_serializer.rb │ ├── todo_serializer.rb │ └── user_serializer.rb ├── services │ ├── application_service.rb │ ├── todo │ │ ├── complete_service.rb │ │ ├── create_service.rb │ │ ├── destroy_service.rb │ │ ├── find_all_service.rb │ │ ├── find_service.rb │ │ └── uncomplete_service.rb │ └── user │ └── create_service.rb └── value_objects └── user_password_value_object.rb v04
  9. 16 directories, 22 files app ├── controllers │ ├── application_controller.rb

    │ ├── todos_controller.rb │ └── users_controller.rb ├── enums │ ├── todo │ │ └── statuses_enum.rb │ └── user │ └── roles_enum.rb ├── models │ ├── application_record.rb │ ├── todo.rb │ └── user.rb ├── permitted_params │ ├── todo │ │ └── permitted_params.rb │ └── user │ └── permitted_params.rb ├── serializers │ ├── application_serializer.rb │ ├── todo │ │ └── serializer.rb │ └── user │ └── serializer.rb ├── services │ ├── application_service.rb │ ├── todo │ │ ├── complete_service.rb │ │ ├── create_service.rb │ │ ├── destroy_service.rb │ │ ├── find_all_service.rb │ │ ├── find_service.rb │ │ └── uncomplete_service.rb │ └── user │ └── create_service.rb └── value_objects └── user └── password_value_object.rb v05
  10. 16 directories, 22 files app ├── controllers │ ├── application_controller.rb

    │ ├── todos_controller.rb │ └── users_controller.rb ├── enums │ ├── todo │ │ └── statuses.rb │ └── user │ └── roles.rb ├── models │ ├── application_record.rb │ ├── todo.rb │ └── user.rb ├── permitted_params │ ├── todo │ │ └── permitted_params.rb │ └── user │ └── permitted_params.rb ├── serializers │ ├── application_serializer.rb │ ├── todo │ │ └── serializer.rb │ └── user │ └── serializer.rb ├── services │ ├── application_service.rb │ ├── todo │ │ ├── complete.rb │ │ ├── create.rb │ │ ├── destroy.rb │ │ ├── find.rb │ │ ├── find_all.rb │ │ └── uncomplete.rb │ └── user │ └── create.rb └── value_objects └── user └── password.rb v06
  11. 06 directories, 22 files app ├── controllers │ ├── application_controller.rb

    │ ├── todos_controller.rb │ └── users_controller.rb └── models ├── application_record.rb ├── application_serializer.rb ├── application_service.rb ├── todo │ ├── permitted_params.rb │ ├── serializer.rb │ ├── services │ │ ├── complete.rb │ │ ├── create.rb │ │ ├── destroy.rb │ │ ├── find.rb │ │ ├── find_all.rb │ │ └── uncomplete.rb │ └── statuses.rb ├── todo.rb ├── user │ ├── password.rb │ ├── permitted_params.rb │ ├── roles.rb │ ├── serializer.rb │ └── services │ └── create.rb └── user.rb v07
  12. 05 directories, 22 files app ├── controllers │ ├── application_controller.rb

    │ ├── todos_controller.rb │ └── users_controller.rb └── models ├── application_record.rb ├── application_serializer.rb ├── application_service.rb ├── todo │ ├── list │ │ ├── add_item.rb │ │ ├── complete_item.rb │ │ ├── destroy_item.rb │ │ ├── find_item.rb │ │ ├── find_items.rb │ │ └── uncomplete_item.rb │ ├── permitted_params.rb │ ├── serializer.rb │ └── statuses.rb ├── todo.rb ├── user │ ├── password.rb │ ├── permitted_params.rb │ ├── register.rb │ ├── roles.rb │ └── serializer.rb └── user.rb v08
  13. 05 directories, 22 files app ├── controllers │ ├── application_controller.rb

    │ ├── todos_controller.rb │ └── users_controller.rb └── models ├── application_record.rb ├── application_serializer.rb ├── application_service.rb ├── todo │ ├── list │ │ ├── add_item.rb │ │ ├── complete_item.rb │ │ ├── destroy_item.rb │ │ ├── find_item.rb │ │ ├── find_items.rb │ │ └── uncomplete_item.rb │ ├── permitted_params.rb │ ├── record.rb │ ├── serializer.rb │ └── statuses.rb └── user ├── password.rb ├── permitted_params.rb ├── record.rb ├── register.rb ├── roles.rb └── serializer.rb v09
  14. 05 directories, 22 files app ├── controllers │ ├── application_controller.rb

    │ ├── todos_controller.rb │ └── users_controller.rb └── models ├── application_record.rb ├── todo │ ├── list │ │ ├── add_item.rb │ │ ├── complete_item.rb │ │ ├── destroy_item.rb │ │ ├── find_item.rb │ │ ├── find_items.rb │ │ └── uncomplete_item.rb │ ├── permitted_params.rb │ ├── record.rb │ ├── serializer.rb │ └── statuses.rb └── user ├── password.rb ├── permitted_params.rb ├── record.rb ├── register.rb ├── roles.rb └── serializer.rb lib ├── application_serializer.rb └── application_service.rb v10
  15. 07 directories, 22 files app ├── controllers │ ├── application_controller.rb

    │ ├── todos │ │ ├── permitted_params.rb │ │ └── serializer.rb │ ├── todos_controller.rb │ ├── users │ │ ├── permitted_params.rb │ │ └── serializer.rb │ └── users_controller.rb └── models ├── application_record.rb ├── todo │ ├── list │ │ ├── add_item.rb │ │ ├── complete_item.rb │ │ ├── destroy_item.rb │ │ ├── find_item.rb │ │ ├── find_items.rb │ │ └── uncomplete_item.rb │ ├── record.rb │ └── statuses.rb └── user ├── password.rb ├── record.rb ├── register.rb └── roles.rb lib ├── application_serializer.rb └── application_service.rb v11
  16. versus app ├── controllers │ ├── application_controller.rb │ ├── todos_controller.rb

    │ └── users_controller.rb ├── enums │ ├── todo_statuses_enum.rb │ └── user_roles_enum.rb ├── models │ ├── application_record.rb │ ├── todo.rb │ └── user.rb ├── permitted_params │ ├── todo_permitted_params.rb │ └── user_permitted_params.rb ├── serializers │ ├── application_serializer.rb │ ├── todo_serializer.rb │ └── user_serializer.rb ├── services │ ├── application_service.rb │ ├── todo │ │ ├── complete_service.rb │ │ ├── create_service.rb │ │ ├── destroy_service.rb │ │ ├── find_all_service.rb │ │ ├── find_service.rb │ │ └── uncomplete_service.rb │ └── user │ └── create_service.rb └── value_objects └── user_password_value_object.rb v04 app ├── controllers │ ├── application_controller.rb │ ├── todos │ │ ├── permitted_params.rb │ │ └── serializer.rb │ ├── todos_controller.rb │ ├── users │ │ ├── permitted_params.rb │ │ └── serializer.rb │ └── users_controller.rb └── models ├── application_record.rb ├── todo │ ├── list │ │ ├── add_item.rb │ │ ├── complete_item.rb │ │ ├── destroy_item.rb │ │ ├── find_item.rb │ │ ├── find_items.rb │ │ └── uncomplete_item.rb │ ├── record.rb │ └── statuses.rb └── user ├── password.rb ├── record.rb ├── register.rb └── roles.rb lib ├── application_serializer.rb └── application_service.rb v11
  17. versus app ├── controllers │ ├── application_controller.rb │ ├── todos_controller.rb

    │ └── users_controller.rb ├── enums │ ├── todo │ │ └── statuses.rb │ └── user │ └── roles.rb ├── models │ ├── application_record.rb │ ├── todo.rb │ └── user.rb ├── permitted_params │ ├── todo │ │ └── permitted_params.rb │ └── user │ └── permitted_params.rb ├── serializers │ ├── application_serializer.rb │ ├── todo │ │ └── serializer.rb │ └── user │ └── serializer.rb ├── services │ ├── application_service.rb │ ├── todo │ │ ├── complete.rb │ │ ├── create.rb │ │ ├── destroy.rb │ │ ├── find.rb │ │ ├── find_all.rb │ │ └── uncomplete.rb │ └── user │ └── create.rb └── value_objects └── user └── password.rb v06 app ├── controllers │ ├── application_controller.rb │ ├── todos │ │ ├── permitted_params.rb │ │ └── serializer.rb │ ├── todos_controller.rb │ ├── users │ │ ├── permitted_params.rb │ │ └── serializer.rb │ └── users_controller.rb └── models ├── application_record.rb ├── todo │ ├── list │ │ ├── add_item.rb │ │ ├── complete_item.rb │ │ ├── destroy_item.rb │ │ ├── find_item.rb │ │ ├── find_items.rb │ │ └── uncomplete_item.rb │ ├── record.rb │ └── statuses.rb └── user ├── password.rb ├── record.rb ├── register.rb └── roles.rb lib ├── application_serializer.rb └── application_service.rb v11
  18. versus app ├── controllers │ ├── application_controller.rb │ ├── todos

    │ │ ├── permitted_params.rb │ │ └── serializer.rb │ ├── todos_controller.rb │ ├── users │ │ ├── permitted_params.rb │ │ └── serializer.rb │ └── users_controller.rb └── models ├── application_record.rb ├── todo │ ├── list │ │ ├── add_item.rb │ │ ├── complete_item.rb │ │ ├── destroy_item.rb │ │ ├── find_item.rb │ │ ├── find_items.rb │ │ └── uncomplete_item.rb │ ├── record.rb │ └── statuses.rb └── user ├── password.rb ├── record.rb ├── register.rb └── roles.rb lib ├── application_serializer.rb └── application_service.rb v11 app ├── controllers │ ├── application_controller.rb │ ├── todos_controller.rb │ └── users_controller.rb └── models ├── application_record.rb ├── application_serializer.rb ├── application_service.rb ├── todo │ ├── list │ │ ├── add_item.rb │ │ ├── complete_item.rb │ │ ├── destroy_item.rb │ │ ├── find_item.rb │ │ ├── find_items.rb │ │ └── uncomplete_item.rb │ ├── permitted_params.rb │ ├── serializer.rb │ └── statuses.rb ├── todo.rb ├── user │ ├── password.rb │ ├── permitted_params.rb │ ├── register.rb │ ├── roles.rb │ └── serializer.rb └── user.rb v08
  19. Racional até aqui Desacoplar código = Promover coesão Coesão =

    Boas abstrações Boas abstrações = Modularização Modularização = Separação de responsabilidades Boa separação de responsabilidades = Coesão
  20. Racional até aqui Desacoplar código = Promover coesão Coesão =

    Boas abstrações Boas abstrações = Modularização Modularização = Separação de responsabilidades Boa separação de responsabilidades = Coesão Se for simples de entender, será fácil de mudar (manter)
  21. WTF/minute ETC (Easy to Change) Lento + Qualidade Alto WTF

    Baixo ETC Baixo WTF Alto ETC Alto WTF Alto ETC Baixo WTF Baixo ETC Coesão (Se for simples de entender, será fácil de manter)
  22. WTF/minute ETC (Easy to Change) Lento + Qualidade Alto WTF

    Baixo ETC Baixo WTF Alto ETC Alto WTF Alto ETC Baixo WTF Baixo ETC Coesão (Se for simples de entender, será fácil de manter)
  23. Velocidade Qualidade Lento + Qualidade sem velocidade sem qualidade sem

    velocidade com qualidade com velocidade sem qualidade com velocidade com qualidade Entregar (Lead time sustentável)
  24. Velocidade Qualidade Lento + Qualidade sem velocidade sem qualidade sem

    velocidade com qualidade com velocidade sem qualidade com velocidade com qualidade Entregar (Lead time sustentável)
  25. Velocidade Qualidade Lento + Qualidade sem velocidade sem qualidade sem

    velocidade com qualidade com velocidade sem qualidade com velocidade com qualidade Entregar (Lead time sustentável)
  26. Velocidade Qualidade Lento + Qualidade sem velocidade sem qualidade sem

    velocidade com qualidade com velocidade sem qualidade com velocidade com qualidade Entregar (Lead time sustentável) Como?
  27. Velocidade Qualidade Lento + Qualidade com velocidade sem qualidade sem

    velocidade com qualidade com velocidade com qualidade sem velocidade sem qualidade Entregar (Lead time sustentável)
  28. Velocidade Qualidade Lento + Qualidade com velocidade sem qualidade sem

    velocidade com qualidade com velocidade com qualidade sem velocidade sem qualidade Make It work Entregar (Lead time sustentável)
  29. Velocidade Qualidade Lento + Qualidade com velocidade sem qualidade sem

    velocidade com qualidade com velocidade com qualidade sem velocidade sem qualidade Make It work Make It right Entregar (Lead time sustentável)
  30. Velocidade Qualidade Lento + Qualidade com velocidade sem qualidade sem

    velocidade com qualidade com velocidade com qualidade sem velocidade sem qualidade Make It work Make It right Make It even better Entregar (Lead time sustentável)
  31. Velocidade Qualidade Lento + Qualidade com velocidade sem qualidade sem

    velocidade com qualidade com velocidade com qualidade sem velocidade sem qualidade Make It work Make It right 1 2 3 Entrega Comportamento Entrega melhorias para a Estrutura Make It even better Entregar (Lead time sustentável)
  32. Velocidade Qualidade Lento + Qualidade com velocidade sem qualidade sem

    velocidade com qualidade com velocidade com qualidade sem velocidade sem qualidade Make It work Make It right Make It even better Entregar (Lead time sustentável)
  33. Velocidade Qualidade Lento + Qualidade com velocidade sem qualidade sem

    velocidade com qualidade com velocidade com qualidade sem velocidade sem qualidade Make It work Make It right Make It even better Entregar (Lead time sustentável)
  34. Problema / Necessidade Solução / Sistema Receber uma transferência Internacional

    1. Criar conta de beneficiário PF / PJ 2. Cadastrar conta bancária PF /PJ 3. Criar conta Internacional p/ o beneficiário 4. Receber pagamento internacional 5. Enviar invoice do pagamento 6. Transferir valor cotado para o beneficiário 1 2 3 4 5 6 Business/Context Driven Development
  35. Problema / Necessidade Solução / Sistema Receber uma transferência Internacional

    1. Criar conta de beneficiário PF / PJ 2. Cadastrar conta bancária PF /PJ 3. Criar conta Internacional p/ o beneficiário 4. Receber pagamento internacional 5. Enviar invoice do pagamento 6. Transferir valor cotado para o beneficiário 1 2 3 4 5 6 ? Casos de uso Business/Context Driven Development
  36. Business/Context Driven Development Sistema = Casos de uso que o

    compõem. 1 2 3 4 5 6 1 2 3 4 5 6 FATO: Todo sistema é orientado por casos de uso, seja de forma explícita ou implícita.
  37. Business/Context Driven Development Sistema = Casos de uso que o

    compõem. 1 2 3 4 5 6 1 2 3 4 5 6 FATO: Todo sistema é orientado por casos de uso, seja de forma explícita ou implícita. Rails way Módulos / Camada dedicada
  38. 1. Pessoas + Momento do negócio 2. Codebase orientado ao

    negócio 3. Separação de responsabilidades (acoplamento e coesão) 4. Escalável (Monolito > Citadel > Microsserviços) Business/Context Driven Development
  39. B/CDD: Pessoas + Momento do negócio Pessoas em diferentes níveis:

    - Junior - Pleno - Senior Momento do negócio: - Experimentação - Transformação - Consolidação
  40. Pessoas em diferentes níveis: - Junior - Pleno - Senior

    Momento do negócio: - Experimentação - Transformação - Consolidação B/CDD: Pessoas + Momento do negócio
  41. Solução / Sistema 1. Criar conta de beneficiário PF /

    PJ 2. Cadastrar conta bancária PF /PJ 3. Criar conta Internacional p/ o beneficiário 4. Receber pagamento internacional 5. Enviar invoice do pagamento 6. Transferir valor cotado para o beneficiário 1 2 3 4 5 6 B/CDD: Codebase orientado ao negócio
  42. Solução / Sistema 1. Criar conta de beneficiário PF /

    PJ 2. Cadastrar conta bancária PF /PJ 3. Criar conta Internacional p/ o beneficiário 4. Receber pagamento internacional 5. Enviar invoice do pagamento 6. Transferir valor cotado para o beneficiário 1 2 3 4 5 6 B/CDD: Codebase orientado ao negócio
  43. Solução / Sistema 1. Criar conta de beneficiário PF /

    PJ 2. Cadastrar conta bancária PF /PJ 3. Criar conta Internacional p/ o beneficiário 4. Receber pagamento internacional 5. Enviar invoice do pagamento 6. Transferir valor cotado para o beneficiário 1 2 3 4 5 6 Beneficiários Pagamentos Invoices B/CDD: Codebase orientado ao negócio
  44. Solução / Sistema 1. Criar conta de beneficiário PF /

    PJ 2. Cadastrar conta bancária PF /PJ 3. Criar conta Internacional p/ o beneficiário 4. Receber pagamento internacional 5. Enviar invoice do pagamento 6. Transferir valor cotado para o beneficiário 1 2 3 4 5 6 Beneficiários Pagamentos Invoices 1. Casos de uso existem dentro de contextos. Ex: app/models/user/password/change.rb 2. No domínio, casos de uso estão no centro, o restante os orbitam (existem para representar as regras de negócio). app/models/user/ password.rb password/ change.rb B/CDD: Codebase orientado ao negócio
  45. Requisições HTTP - Routes -> Controllers - Rack apps mounted

    - Rails Engines - Sinatra CLI - Rake tasks - Whenever - bin/rails runner Background Jobs - Active Job - Sidekiq Entry points em uma aplicação Ruby on Rails B/CDD: Separação de responsabilidades Context Entry Point Input Output Use Case Contrato/ Tradutor
  46. Requisições HTTP - Routes -> Controllers - Rack apps mounted

    - Rails Engines - Sinatra CLI - Rake tasks - Whenever - bin/rails runner Background Jobs - Active Job - Sidekiq Entry points em uma aplicação Ruby on Rails B/CDD: Separação de responsabilidades Context Entry Point Input Output Use Case Contrato/ Tradutor São entry points por serem processos isolados (a nível de SO).
  47. B/CDD: Escalável Monolito (Modular) Citadel (Monolito Modular + Serviços satélites)

    Microsseviços Context Entry Point Input Output Use Case Contrato/ Tradutor
  48. Obrigado @serradura [email protected] ~50 horas de dedicação para preparar esse

    conteúdo. ;) Agradecimentos: Pedro Basilio Haroldo Furtado Tomás Coelho Vitor Avelino Ralf Schmitz Bongiolo Luiz Vasconcellos Wedson Lima Diego Linhares Mauricio Carvalho / Husky