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

Enemy Of The State

Enemy Of The State

Building front end JavaScript applications can be hard. In part, because they are just giant balls of events and state. And just like every problem in programming the more of something you have, the harder it becomes to manage. In this talk we are going to take a critical look at some of the patterns we see being applied in frameworks like ember, and backbone to see if the give us ways of handling state and state transition in a scaleable, maintainable fashion. and then take a look at some tactics you can use to help you better embrace both state and events, without sacrificing clarity in your architecture.

Amy Palamountain

April 10, 2014
Tweet

More Decks by Amy Palamountain

Other Decks in Programming

Transcript

  1. ENEMY
    of STATE
    the

    View full-size slide

  2. State & events

    View full-size slide

  3. State & events
    a shit load of

    View full-size slide

  4. as complexity increases
    our sanity decreases

    View full-size slide

  5. conflated models

    View full-size slide

  6. conflated models
    views
    conflated

    View full-size slide

  7. conflated models
    views
    state
    conflated
    conflated

    View full-size slide

  8. conflated models
    views
    state
    events
    conflated
    conflated
    conflated

    View full-size slide

  9. everything is
    terrible

    View full-size slide

  10. design
    http://www.flickr.com/photos/neononac/
    patterns

    View full-size slide

  11. mv what ever

    View full-size slide

  12. Server versus client

    View full-size slide

  13. server versus client

    View full-size slide

  14. where the
    magic happens
    Models

    View full-size slide

  15. Views
    presentation
    of the magic

    View full-size slide

  16. coordination
    of the magic
    Controllers

    View full-size slide

  17. Routes
    interaction
    with the magic

    View full-size slide

  18. on the server
    State

    View full-size slide

  19. Stateon the server

    View full-size slide

  20. How do we
    transition state ?

    View full-size slide

  21. and events
    Routes
    address state

    View full-size slide

  22. matches a pattern
    Router

    View full-size slide

  23. matches a pattern
    Router
    has action invoked
    Controller

    View full-size slide

  24. matches a pattern
    Router
    has action invoked
    Controller
    look up and update
    Model

    View full-size slide

  25. matches a pattern
    Router
    has action invoked
    Controller
    look up and update
    Model
    snapshot returned
    View

    View full-size slide

  26. client server boundary
    addressable & linear

    View full-size slide

  27. server versus Client

    View full-size slide

  28. STATEFUL CLIENTS
    no boundaries

    View full-size slide

  29. the state space
    no boundaries

    View full-size slide

  30. models
    the state space
    no boundaries

    View full-size slide

  31. models
    view state
    the state space
    no boundaries

    View full-size slide

  32. models
    view state
    the state space
    no boundaries
    application state

    View full-size slide

  33. {❴
    {❴
    state and
    transitions
    inside the
    boundary

    View full-size slide

  34. need decent plans
    non linear state space
    because, complicated

    View full-size slide

  35. model
    view
    controller
    stateful
    presentation patterns

    View full-size slide

  36. routes
    model
    view
    controller
    stateful
    presentation patterns

    View full-size slide

  37. whats all
    this then?
    routes
    model
    view
    controller
    stateful
    presentation patterns

    View full-size slide

  38. addressability
    we still need

    View full-size slide

  39. play out on the client
    mv what ever you want to call it
    how does

    View full-size slide

  40. !
    !
    /** Models **/
    Animal = Backbone.Model.extend({});
    PartyAnimals = Backbone.Collection.extend({
    model: Animal
    });
    !
    /** View /Controller / Worlds most poorly named object **/
    PartyAnimalView = Backbone.View.extend({
    !
    template: "#party-animal-template",
    render: function(){
    var html = $(this.template).tmpl(this.collection);
    $(this.el).html(html);

    View full-size slide

  41. encapsulation
    breaking

    View full-size slide

  42. !
    !
    AppRouter = Backbone.Router.extend({
    !
    routes: {
    '#/party': 'startTheParty',
    '#/party/uninvite/:animal': 'revokePartyRights'
    },
    revokePartyRights: function(animal){
    model = partyAnimalCollection.find(animal);
    model.destroy();
    $("#animal-party").remove();
    },
    !
    startTheParty: function(animal){
    var view = new PartyView({ collection : partyAnimalCollection });
    partyAnimalCollection.fetch();
    view.render();
    }
    !
    });
    !

    View full-size slide

  43. !
    !
    AppRouter = Backbone.Router.extend({
    !
    routes: {
    '#/party': 'startTheParty',
    '#/party/uninvite/:animal': 'revokePartyRights'
    },
    revokePartyRights: function(animal){
    model = partyAnimalCollection.find(animal);
    model.destroy();
    $("#animal-party").remove();
    },
    !
    startTheParty: function(animal){
    var view = new PartyView({ collection : partyAnimalCollection });
    partyAnimalCollection.fetch();
    view.render();
    }
    !
    });
    !

    View full-size slide

  44. SECOND CLASS
    citizens

    View full-size slide

  45. rows in a database
    our models are more than
    they are rich and interactive

    View full-size slide

  46. Routes
    are a feature

    View full-size slide

  47. enemy
    are
    routes the

    View full-size slide

  48. the enemy
    over use of
    routes is

    View full-size slide

  49. shoe horned
    a web server
    onto the client

    View full-size slide

  50. address state
    but never transitions

    View full-size slide

  51. refactor
    transitions

    View full-size slide

  52. !
    /** Models **/
    Animal = Backbone.Model.extend({});
    PartyAnimals = Backbone.Collection.extend({
    model: Animal
    });
    !
    !
    /** View /Controller / Worlds most poorly named object **/
    PartyAnimalView = Backbone.View.extend({
    !
    el: "#animal-party",
    template: "#party-animal-template",

    View full-size slide

  53. no more unnecessary
    look ups

    View full-size slide

  54. and the view
    is in charge

    View full-size slide

  55. addressability is still
    a key concern

    View full-size slide

  56. embraces events
    an architecture which

    View full-size slide

  57. models
    Syncs state,
    Transition state.
    Raises events

    View full-size slide

  58. models
    Syncs state,
    Transition state.
    Raises events
    views
    Handles model events
    Handles DOM events

    View full-size slide

  59. models
    Syncs state,
    Transition state.
    Raises events
    views
    Handles model events
    Handles DOM events
    templates
    HTML rendered
    by the view

    View full-size slide

  60. controller
    Initialises models and views
    keeps track of their placement within
    a given container
    models
    Syncs state,
    Transition state.
    Raises events
    views
    Handles model events
    Handles DOM events
    templates
    HTML rendered
    by the view

    View full-size slide

  61. module
    A strand alone component

    View full-size slide

  62. The secret to building large
    apps is never build large apps.
    Break your application into
    small pieces. Then, assemble
    those testable, bite-sized
    pieces into your big application ”

    Justin Meyer, author JavaScriptMVC

    View full-size slide

  63. never place themselves
    a modules views
    on the application shell

    View full-size slide

  64. !
    Layout
    Composition

    View full-size slide

  65. !
    !
    !
    !
    !
    var rm = new Marionette.RegionManager();
    !
    var region = rm.addRegion("foo", “#bar”);
    !
    var regions = rm.addRegions({
    mainContent: "#mainContent",
    sideBar: “#sideBar"
    });
    !
    regions.mainContent.show(myView);

    View full-size slide

  66. !
    !
    !
    !
    !
    var composer = new LayoutComposer();
    !
    var region = composer.addRegion(“mainContent", “#mainContent");
    !
    var composer = rm.addRegions({
    mainContent: "#mainContent",
    sideBar: “#sideBar"
    });
    !
    composer.mainContent.show(suchModule);
    !
    // region.show() function
    // will supply the module with the el to render to

    View full-size slide

  67. layout composer
    Initialises models and views
    keeps track of their placement within
    a given container
    module
    A strand alone component

    View full-size slide

  68. the dispatcher

    View full-size slide

  69. !
    !
    !
    !
    !
    !
    module.exports = Dispatcher = (function() {
    !
    Dispatcher.extend = Backbone.Model.extend;
    !
    _.extend(Dispatcher.prototype, EventBroker);
    !
    Dispatcher.prototype.previousRoute = null;
    !
    Dispatcher.prototype.currentModules = null;
    !
    Dispatcher.prototype.currentRoute = null;
    !
    Dispatcher.prototype.initialize = function(options) {

    View full-size slide

  70. layout composer
    Initialises models and views
    keeps track of their placement within
    a given container
    module
    A strand alone component
    dispatcher
    Loads new modules
    disposes of old

    View full-size slide

  71. layout composer
    Initialises models and views
    keeps track of their placement within
    a given container
    module
    A strand alone component
    dispatcher
    Loads new modules
    disposes of old
    router
    Mediates address bar events

    View full-size slide

  72. composable and event driven
    a new
    design

    View full-size slide

  73. scaling a state space
    can be really hard work
    TL;DR

    View full-size slide

  74. especially when we
    don’t separate concerns
    TL;DR

    View full-size slide

  75. address states
    never transitions
    TL;DR

    View full-size slide

  76. take inspiration
    and evolve ideas
    TL;DR

    View full-size slide

  77. dont build
    servers on the client
    TL;DR

    View full-size slide

  78. Thank you
    @ammeep
    amy.palamounta.in
    internet related activities:
    github.com/ammeep ENEMY
    ofSTATE
    the
    chaplinjs.org
    marionettejs.com

    View full-size slide