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

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 Slide

  2. View Slide

  3. ammeep

    View Slide

  4. GitHub

    View Slide

  5. State

    View Slide

  6. State & events

    View Slide

  7. State & events
    a shit load of

    View Slide

  8. as complexity increases
    our sanity decreases

    View Slide

  9. conflated models

    View Slide

  10. conflated models
    views
    conflated

    View Slide

  11. conflated models
    views
    state
    conflated
    conflated

    View Slide

  12. conflated models
    views
    state
    events
    conflated
    conflated
    conflated

    View Slide

  13. everything is
    terrible

    View Slide

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

    View Slide

  15. ideas

    View Slide

  16. mv what ever

    View Slide

  17. Server versus client

    View Slide

  18. server versus client

    View Slide

  19. where the
    magic happens
    Models

    View Slide

  20. Views
    presentation
    of the magic

    View Slide

  21. coordination
    of the magic
    Controllers

    View Slide

  22. Routes
    interaction
    with the magic

    View Slide

  23. on the server
    State

    View Slide

  24. Stateon the server

    View Slide

  25. How do we
    transition state ?

    View Slide

  26. and events
    Routes
    address state

    View Slide

  27. matches a pattern
    Router

    View Slide

  28. matches a pattern
    Router
    has action invoked
    Controller

    View Slide

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

    View Slide

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

    View Slide

  31. client server boundary
    addressable & linear

    View Slide

  32. server versus Client

    View Slide

  33. STATEFUL CLIENTS
    no boundaries

    View Slide

  34. the state space
    no boundaries

    View Slide

  35. models
    the state space
    no boundaries

    View Slide

  36. models
    view state
    the state space
    no boundaries

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  40. model
    view
    controller
    stateful
    presentation patterns

    View Slide

  41. routes
    model
    view
    controller
    stateful
    presentation patterns

    View Slide

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

    View Slide

  43. addressability
    we still need

    View Slide

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

    View Slide

  45. !
    !
    /** 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 Slide

  46. encapsulation
    breaking

    View Slide

  47. !
    !
    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 Slide

  48. !
    !
    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 Slide

  49. SECOND CLASS
    citizens

    View Slide

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

    View Slide

  51. Routes
    are a feature

    View Slide

  52. enemy
    are
    routes the

    View Slide

  53. the enemy
    over use of
    routes is

    View Slide

  54. shoe horned
    a web server
    onto the client

    View Slide

  55. address state
    but never transitions

    View Slide

  56. refactor
    transitions

    View Slide

  57. !
    /** 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 Slide

  58. no more unnecessary
    look ups

    View Slide

  59. and the view
    is in charge

    View Slide

  60. addressability is still
    a key concern

    View Slide

  61. embraces events
    an architecture which

    View Slide

  62. models
    Syncs state,
    Transition state.
    Raises events

    View Slide

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

    View Slide

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

    View Slide

  65. 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 Slide

  66. module
    A strand alone component

    View Slide

  67. 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 Slide

  68. Modules

    View Slide

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

    View Slide

  70. !
    Layout
    Composition

    View Slide

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

    View Slide

  72. !
    !
    !
    !
    !
    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 Slide

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

    View Slide

  74. the dispatcher

    View Slide

  75. the router

    View Slide

  76. !
    !
    !
    !
    !
    !
    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 Slide

  77. 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 Slide

  78. 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 Slide

  79. composable and event driven
    a new
    design

    View Slide

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

    View Slide

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

    View Slide

  82. address states
    never transitions
    TL;DR

    View Slide

  83. take inspiration
    and evolve ideas
    TL;DR

    View Slide

  84. dont build
    servers on the client
    TL;DR

    View Slide

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

    View Slide