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

Rewriting code and culture - RubyConf Aus

Rewriting code and culture - RubyConf Aus

This is the story of a company that survived a much needed transformation of its product and codebase, but most importantly, of its culture. There's no real prescription for being agile. It's about the journey a team takes to discover how to best work together and deliver great products.

In this presentation, I'll share a candid view of a team trying to overcome a slow product development process. How we refactored our way out of badly coupled code, moved to continuous deployment, and greatly improved our approach to product and software development.

From Ruby Conf Australia, Melbourne 2015.

Sabrina Leandro

February 06, 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. View Slide

  5. View Slide

  6. This is hell!

    View Slide

  7. Lessons on rewriting code

    View Slide

  8. Know your product

    View Slide

  9. View Slide

  10. View Slide

  11. View Slide

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

    View Slide

  13. songkick.com
    Rails app
    Ruby services

    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. • Define project scope
    • Have a clear deadline
    • Weekly checkpoints
    • No new features
    Know when it ends

    View Slide

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

    View Slide

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

    View Slide

  21. Learn to iterate

    View Slide

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

    View Slide

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

    View Slide

  24. 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

  25. New front-end architecture

    View Slide

  26. venue-info
    event-brief
    additional-details
    event-social related-events
    the
    Event
    page

    View Slide

  27. 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

  28. 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

  29. class PageModels::Event < PageModels::Base
    def brief
    PageModels::Event::Brief.new(@event)
    end
    end
    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

  30. class PageModels::Event::Brief
    def event_title
    @event.festival? ?
    @event.festival_name :
    @event.headliners.first.name
    end
    end
    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

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

    View Slide

  32. show.html.erb

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

    _brief.html.erb

    <%= brief.event_title %>

    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

  33. event.css
    @import ‘components/event-brief.css’;
    event-brief.css
    .brief h1 {
    color: #f80046;
    }
    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

  34. From idea to code.
    Shared language

    View Slide

  35. Fast release cycle = fast build

    View Slide

  36. Delete or rewrite tests.
    Fast release cycle = fast build

    View Slide

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

    View Slide

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

    View Slide

  39. First step towards a
    service-oriented
    architecture

    View Slide

  40. class EventsController <
    ApplicationController
    def show
    @event = Event.find(params[:id])

    end
    end
    class Event < ActiveRecord::Base
    end
    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

  41. 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

  42. 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
    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

  43. 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
    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

  44. class Services::EventListings
    def event_from_id(id)
    response = http.get(“/events/#{id}")
    JSON.parse(response.body)
    end
    end
    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

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

    View Slide

  46. View Slide

  47. View Slide

  48. Happiness

    View Slide

  49. Cultural changes

    View Slide

  50. Rewriting culture

    View Slide

  51. Rewriting culture
    …through collaboration between
    developers, designers, and product
    managers.

    View Slide

  52. Rewriting culture
    …through collaboration between
    developers, designers, and product
    managers.
    Collaboration builds shared understanding.

    View Slide

  53. Culture in practice

    View Slide

  54. • Shared language
    Culture in practice

    View Slide

  55. • Shared language
    • Small releases
    Culture in practice

    View Slide

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

    View Slide

  57. Close collaboration from the start
    • Developers involved in the idea
    development stage
    • Kick off meeting to define what we’re
    building and why
    Culture in practice

    View Slide

  58. Developer and designer pairing
    • Browser becomes the art board
    • Wider team gets involved with the way
    the product looks and feels
    Culture in practice

    View Slide

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

    View Slide

  60. Learn to collaborate and work in a
    multidisciplinary team.
    They make for happier teams, better products,
    and can even improve your code’s quality.
    Rewriting culture

    View Slide

  61. 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/
    :) https://www.youtube.com/watch?v=3noDS5uoK8o

    View Slide

  62. Thanks!
    Sabrina Leandro
    @saleandro

    View Slide