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.

B83d5b590577969ee79a5ad845411a7d?s=128

Amy Palamountain

April 10, 2014
Tweet

Transcript

  1. ENEMY of STATE the

  2. None
  3. ammeep

  4. GitHub

  5. State

  6. State & events

  7. State & events a shit load of

  8. as complexity increases our sanity decreases

  9. conflated models

  10. conflated models views conflated

  11. conflated models views state conflated conflated

  12. conflated models views state events conflated conflated conflated

  13. everything is terrible

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

  15. ideas

  16. mv what ever

  17. Server versus client

  18. server versus client

  19. where the magic happens Models

  20. Views presentation of the magic

  21. coordination of the magic Controllers

  22. Routes interaction with the magic

  23. on the server State

  24. Stateon the server

  25. How do we transition state ?

  26. and events Routes address state

  27. matches a pattern Router

  28. matches a pattern Router has action invoked Controller

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

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

    and update Model snapshot returned View
  31. client server boundary addressable & linear

  32. server versus Client

  33. STATEFUL CLIENTS no boundaries

  34. the state space no boundaries

  35. models the state space no boundaries

  36. models view state the state space no boundaries

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

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

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

  40. model view controller stateful presentation patterns

  41. routes model view controller stateful presentation patterns

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

    patterns
  43. addressability we still need

  44. play out on the client mv what ever you want

    to call it how does
  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);
  46. encapsulation breaking

  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(); } ! }); !
  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(); } ! }); !
  49. SECOND CLASS citizens

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

    are rich and interactive
  51. Routes are a feature

  52. enemy are routes the

  53. the enemy over use of routes is

  54. shoe horned a web server onto the client

  55. address state but never transitions

  56. refactor transitions ‘

  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",
  58. no more unnecessary look ups

  59. and the view is in charge

  60. addressability is still a key concern

  61. embraces events an architecture which

  62. models Syncs state, Transition state. Raises events

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

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

    events Handles DOM events templates HTML rendered by the view
  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
  66. module A strand alone component

  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
  68. Modules

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

  70. ! Layout Composition

  71. ! ! ! ! ! var rm = new Marionette.RegionManager();

    ! var region = rm.addRegion("foo", “#bar”); ! var regions = rm.addRegions({ mainContent: "#mainContent", sideBar: “#sideBar" }); ! regions.mainContent.show(myView);
  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
  73. layout composer Initialises models and views keeps track of their

    placement within a given container module A strand alone component
  74. the dispatcher

  75. the router

  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) {
  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
  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
  79. composable and event driven a new design

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

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

  82. address states never transitions TL;DR

  83. take inspiration and evolve ideas TL;DR

  84. dont build servers on the client TL;DR

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

    the chaplinjs.org marionettejs.com