$30 off During Our Annual Pro Sale. View Details »

Rewriting code and culture - RubyConf.pt

Rewriting code and culture - RubyConf.pt

Sabrina Leandro

September 16, 2015
Tweet

More Decks by Sabrina Leandro

Other Decks in Technology

Transcript

  1. Rewriting code and culture
    Sabrina Leandro
    @saleandro

    View Slide

  2. 1. Lessons from a rewrite project
    2. Some code
    3. Cultural changes

    View Slide

  3. A story about…

    View Slide

  4. A metaphor

    View Slide

  5. A metaphor

    View Slide

  6. View Slide

  7. This is hell!

    View Slide

  8. Lessons on rewriting code

    View Slide

  9. Know your product

    View Slide

  10. View Slide

  11. View Slide

  12. View Slide

  13. That is, where the impact of the
    changes will be seen sooner.
    Start where it hurts the most

    View Slide

  14. songkick.com
    Rails app
    Ruby services

    View Slide

  15. songkick.com
    Rails app
    Ruby services

    View Slide

  16. songkick.com
    Rails app
    Ruby services
    Land of legacy dragons

    View Slide

  17. Build a new, simplified web app
    based on core iPhone features
    so that we can improve
    the immediate velocity roadblocks
    and move onto building quickly
    on top of this core foundation.
    One main goal

    View Slide

  18. Know when it ends

    View Slide

  19. Define project scope
    Know when it ends

    View Slide

  20. Define project scope
    Have a clear deadline
    Know when it ends

    View Slide

  21. Define project scope
    Have a clear deadline
    Weekly checkpoints
    Know when it ends

    View Slide

  22. Define project scope
    Have a clear deadline
    Weekly checkpoints
    Know when it ends

    View Slide

  23. Define project scope
    Have a clear deadline
    Weekly checkpoints
    No new features
    Know when it ends

    View Slide

  24. Deleting your favourite features is hard!
    But when you know your product, you
    can be ruthless.
    Deleting is faster than rewriting

    View Slide

  25. Changes in master.
    Release incrementally.
    Improve your release process.
    Validate your assumptions

    View Slide

  26. Fast release cycle needs fast build

    View Slide

  27. Fast release cycle needs fast build
    Delete or rewrite tests.

    View Slide

  28. Cost of making a small change must be small.
    Fast release cycle needs fast build
    Delete or rewrite tests.

    View Slide

  29. Cost of making a small change must be small.
    Monitor errors in production.
    Fast release cycle needs fast build
    Delete or rewrite tests.

    View Slide

  30. Learn to iterate

    View Slide

  31. Release cycle is more than software
    development.
    Learn to iterate

    View Slide

  32. Release cycle is more than software
    development.
    Learn to iterate

    View Slide

  33. Release cycle is more than software
    development.
    Give developers the right context, and
    trust them to make the right decisions.
    Learn to iterate

    View Slide

  34. New front-end architecture

    View Slide

  35. tickets
    attendance-
    listing
    venue-info related-
    events
    additional-details
    event-brief
    event-social
    the
    Event
    page

    View Slide

  36. controllers/
    events_controller.rb
    models/
    event.rb
    page_models/
    event.rb
    event/
    brief.rb
    models/
    event.rb
    services/
    event_listings.rb
    views/
    events/
    _brief.html.erb
    show.html.erb
    assets/
    stylesheets/
    event.css
    components/
    event-brief.css

    View Slide

  37. The event brief component

    View Slide

  38. controllers/
    events_controller.
    rb
    models/
    event.rb
    page_models/
    event.rb
    event/
    brief.rb
    models/
    event.rb
    services/
    event_listings.rb
    views/
    events/
    _brief.html.erb
    show.html.erb
    assets/
    stylesheets/
    event.css
    components/
    event-brief.css
    class EventsController <
    ApplicationController
    def show
    @page =
    PageModels::Event.new(event)
    end
    end

    View Slide

  39. controllers/
    events_controller.rb
    models/
    event.rb
    page_models/
    event.rb
    event/
    brief.rb
    models/
    event.rb
    services/
    event_listings.rb
    views/
    events/
    _brief.html.erb
    show.html.erb
    assets/
    stylesheets/
    event.css
    components/
    event-brief.css
    class PageModels::Event <
    PageModels::Base
    def brief
    PageModels::Event::Brief.new(
    @event)
    end
    end

    View Slide

  40. controllers/
    events_controller.rb
    models/
    event.rb
    page_models/
    event.rb
    event/
    brief.rb
    models/
    event.rb
    services/
    event_listings.rb
    views/
    events/
    _brief.html.erb
    show.html.erb
    assets/
    stylesheets/
    event.css
    components/
    event-brief.css
    class PageModels::Event::Brief
    def event_title
    @event.festival? ?
    @event.festival_name :
    @event.headliners.first.name
    end
    end

    View Slide

  41. View Slide

  42. p {
    color: #000000;
    }

    View Slide

  43. p {
    color: #000000;
    }
    p {
    color: #008000 !important;
    }

    View Slide

  44. p {
    color: #000000;
    }
    p {
    color: #008000 !important;
    }
    p {
    color: #f80046 !really-important!;
    }

    View Slide

  45. Duplication in front-end code is okay.
    DRY is for domain models

    View Slide

  46. controllers/
    events_controller.rb
    models/
    event.rb
    page_models/
    event.rb
    event/
    brief.rb
    models/
    event.rb
    services/
    event_listings.rb
    views/
    events/
    _brief.html.erb
    show.html.erb
    assets/
    stylesheets/
    event.css
    components/
    event-brief.css
    show.html.erb

    <%= component(:brief,
    @page.brief)%>

    _brief.html.erb

    <%= brief.event_title
    %>

    View Slide

  47. controllers/
    events_controller.rb
    models/
    event.rb
    page_models/
    event.rb
    event/
    brief.rb
    models/
    event.rb
    services/
    event_listings.rb
    views/
    events/
    _brief.html.erb
    show.html.erb
    assets/
    stylesheets/
    event.css
    components/
    event-
    brief.css
    event.css
    @import ‘components/event-
    brief.css’;
    event-brief.css
    .brief h1 {
    color: #000000;
    }
    .brief p {
    color: #f80046;
    }

    View Slide

  48. From idea
    to code.
    Shared language

    View Slide

  49. First step towards a
    service-oriented
    architecture

    View Slide

  50. controllers/
    events_controller.
    rb
    models/
    event.rb
    page_models/
    event.rb
    event/
    brief.rb
    models/
    event.rb
    services/
    event_listings.rb
    views/
    events/
    _brief.html.erb
    show.html.erb
    assets/
    stylesheets/
    event.css
    components/
    event-brief.css
    class EventsController <
    ApplicationController
    def show
    @event =
    Event.find(params[:id])

    end
    end
    class Event < ActiveRecord::Base
    end

    View Slide

  51. controllers/
    events_controller.
    rb
    models/
    event.rb
    page_models/
    event.rb
    event/
    brief.rb
    models/
    event.rb
    services/
    event_listings.rb
    views/
    events/
    _brief.html.erb
    show.html.erb
    assets/
    stylesheets/
    event.css
    components/
    event-brief.css
    class EventsController <
    ApplicationController
    def show
    event = Models::Event.from_id
    params[:id]
    @page =
    PageModels::Event.new(event)
    end
    end

    View Slide

  52. controllers/
    events_controller.rb
    models/
    event.rb
    page_models/
    event.rb
    event/
    brief.rb
    models/
    event.rb
    services/
    event_listings.rb
    views/
    events/
    _brief.html.erb
    show.html.erb
    assets/
    stylesheets/
    event.css
    components/
    event-brief.css
    class Models::Event
    def self.from_id(id)
    data =
    Services.event_listings.event_
    from_id(id)
    new(data)
    end
    def initialize(data)
    @id = data[‘id’]
    @date =
    Date.parse(data[‘date’])
    # etc.
    end
    end

    View Slide

  53. controllers/
    events_controller.rb
    models/
    event.rb
    page_models/
    event.rb
    event/
    brief.rb
    models/
    event.rb
    services/
    event_listings.
    rb
    views/
    events/
    _brief.html.erb
    show.html.erb
    assets/
    stylesheets/
    event.css
    components/
    event-brief.css
    class Services::EventListings
    def event_from_id(id)
    ar_event = ::Event.find(id)
    ar_event.to_hash
    end
    end
    class Event < ActiveRecord::Base
    def to_hash
    {
    'id' => id,
    'date' => date.to_s,
    # etc.
    }
    end
    end

    View Slide

  54. songkick.com
    Rails app
    Ruby services
    Land of legacy dragons

    View Slide

  55. controllers/
    events_controller.rb
    models/
    page_models/
    event.rb
    event/
    brief.rb
    models/
    event.rb
    services/
    event_listings.
    rb
    views/
    events/
    _brief.html.erb
    show.html.erb
    assets/
    stylesheets/
    event.css
    components/
    event-brief.css
    class Services::EventListings
    def event_from_id(id)
    response =
    http.get(“/events/#{id}")
    JSON.parse(response.body)
    end
    end

    View Slide

  56. event-listings accounts trackings notifications
    songkick.com
    Rails app

    View Slide

  57. event-listings accounts trackings notifications
    songkick.com
    Rails app

    View Slide

  58. Land of legacy dragons
    event-listings accounts trackings notifications
    songkick.com
    Rails app

    View Slide

  59. View Slide

  60. Happiness

    View Slide

  61. Cultural changes

    View Slide

  62. Rewriting culture

    View Slide

  63. Rewriting culture
    …through collaboration between
    developers, designers, product
    managers, testers, support team, etc…

    View Slide

  64. Rewriting culture
    …through collaboration between
    developers, designers, product
    managers, testers, support team, etc…
    Collaboration builds shared understanding.

    View Slide

  65. Business goals User needs
    Technical
    feasibility

    View Slide

  66. Business goals User needs
    Technical
    feasibility
    Product magic

    View Slide

  67. Product teams
    Product
    manager
    Design lead
    Tech lead

    View Slide

  68. Culture in practice

    View Slide

  69. • Shared language
    Culture in practice

    View Slide

  70. • Shared language
    • Small and frequent releases
    Culture in practice

    View Slide

  71. • Shared language
    • Small and frequent releases
    • Iterate design and product
    development
    Culture in practice

    View Slide

  72. Before
    Culture in practice

    View Slide

  73. Feature Kick-off meetings
    Before
    Culture in practice

    View Slide

  74. Culture in practice
    Before

    View Slide

  75. Culture in practice
    Designer and
    developer pairing
    Before

    View Slide

  76. A clean codebase is just a
    means to an end.
    Rewriting culture

    View Slide

  77. Learn to collaborate and work in a
    cross-functional team.
    For happier teams, better products, and
    even improved code quality.
    Rewriting culture

    View Slide

  78. Links
    The Client side of SOA
    http://devblog.songkick.com/2012/08/30/the-client-
    side-of-soa/
    Path to SOA
    http://devblog.songkick.com/2012/09/06/the-path-to-
    soa/
    Our object-based Rails frontend
    http://devblog.songkick.com/2012/09/14/our-object-
    based-rails- frontend/

    View Slide

  79. Thanks!
    Sabrina Leandro
    @saleandro

    View Slide