Your SlideShare is downloading. ×
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Zombie Code
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Zombie Code

1,278

Published on

Have you ever had the need to figure out how to survive a Javascript Zombiecodepocalipse? Have you ever dreamt about loads of living legacy code and the urge to run away from it? Hundreds of lines of …

Have you ever had the need to figure out how to survive a Javascript Zombiecodepocalipse? Have you ever dreamt about loads of living legacy code and the urge to run away from it? Hundreds of lines of code tightly coupled and hardly understandable there were trying to catch you?

I’ve been there and I’m a survivor because I learned the art of refactoring.
This talk is about how to deal with features request, deadlines and still increase the maintainability of your code.

Published in: Technology, Design
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,278
On Slideshare
0
From Embeds
0
Number of Embeds
6
Actions
Shares
0
Downloads
17
Comments
0
Likes
3
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. TALK
  • 2. Zombie Code
  • 3. Zombie Codehow to survive a JavascriptZombiecodeapocalypse
  • 4. First things firstmy name is@cedmaxI work for ShazamI organizeconferences withFrom The Front
  • 5. DISCLAIMER
  • 6. DISCLAIMERI’m strongly opinionated
  • 7. DISCLAIMERI’m strongly opinionatedit’s a gift and a curse
  • 8. BasicallyZombies?
  • 9. BasicallyZombies?
  • 10. Zombies!“Brains, BRAINS, BRains, brains, BRAINS.BRaiNS, brains, Brains, BRAINS, BRains,brains, BRAINS.BRAINS, BRains, brains, BRAINS, brains.”Ryan Mecum
  • 11. ZOMBIE CODE?
  • 12. it’s not dead codehttp://alfasin.com/i-see-dead-code-homage-for-intellij-idea/
  • 13. How to identifyZombie CODE?
  • 14. What I can tell is..
  • 15. It may seems harmlesshttp://couchpotatofiles.wordpress.com/2012/03/20/the-walking-dead-ups-the-death-count-and-the-ratings/
  • 16. http://couchpotatofiles.wordpress.com/2012/03/20/the-walking-dead-ups-the-death-count-and-the-ratings/but it’s NOT
  • 17. and it will, eventuallyhttp://imgur.com/r/SRDBroke/JimqKCODE
  • 18. during estimation
  • 19. during debugging
  • 20. during development
  • 21. It is dumb codethat makes you dumb as well
  • 22. Hopefully it’s not too latehttp://tacticaltshirts.com/shop/shirt-zombies-eat-brains/
  • 23. Whats that smell?Zombies smell worse thananything you can imagineLilith Saintcrow, Strange Angels
  • 24. TIp #1Code should be appealing
  • 25. function validate( options ) {// if nothing is selected, return nothing; cant chain anywayif ( !this.length ) {if ( options && options.debug && window.console ) {console.warn( "Nothing selected, cant validate, returning nothing." );}return;}// check if a validator for this form was already createdvar validator = $.data( this[0], "validator" );if ( validator ) {return validator;}// Add novalidate tag if HTML5.this.attr( "novalidate", "novalidate" );validator = new $.validator( options, this[0] );$.data( this[0], "validator", validator );if ( validator.settings.onsubmit ) {this.validateDelegate( ":submit", "click", function( event ) {if ( validator.settings.submitHandler ) {validator.submitButton = event.target;}
  • 26. // allow suppressing validation by adding a cancel class to thesubmit buttonif ( $(event.target).hasClass("cancel") ) {validator.cancelSubmit = true;}// allow suppressing validation by adding the html5 formnovalidateattribute to the submit buttonif ( $(event.target).attr("formnovalidate") !== undefined ) {validator.cancelSubmit = true;}});// validate the form on submitthis.submit( function( event ) {if ( validator.settings.debug ) {// prevent form submit to be able to see console outputevent.preventDefault();}function handle() {var hidden;if ( validator.settings.submitHandler ) {if ( validator.submitButton ) {// insert a hidden input as a replacement for the missingsubmit buttonhidden = $("<input type=hidden/>").attr("name",validator.submitButton.name).val( $(validator.submitButton).val() ).appendTo(validator.currentForm);}
  • 27. validator.settings.submitHandler.call( validator,validator.currentForm, event );if ( validator.submitButton ) {// and clean up afterwards; thanks to no-block-scope, hiddencan be referencedhidden.remove();}return false;}return true;}// prevent submit for invalid forms or custom submit handlersif ( validator.cancelSubmit ) {validator.cancelSubmit = false;return handle();}if ( validator.form() ) {if ( validator.pendingRequest ) {validator.formSubmitted = true;return false;}return handle();} else {validator.focusInvalid();return false;}});}return validator;}
  • 28. HOW LONG IS THAT?
  • 29. function validate( options ) {// if nothing is selected, return nothing; cant chain anywayif ( !this.length ) {if ( options && options.debug && window.console ) {console.warn( "Nothing selected, cant validate, returning nothing." );}return;}// check if a validator for this form was already createdvar validator = $.data( this[0], "validator" );if ( validator ) {return validator;}// Add novalidate tag if HTML5.this.attr( "novalidate", "novalidate" );validator = new $.validator( options, this[0] );$.data( this[0], "validator", validator );if ( validator.settings.onsubmit ) {this.validateDelegate( ":submit", "click", function( event ) {if ( validator.settings.submitHandler ) {validator.submitButton = event.target;}// allow suppressing validation by adding a cancel class to the submit buttonif ( $(event.target).hasClass("cancel") ) {validator.cancelSubmit = true;}// allow suppressing validation by adding the html5 formnovalidate attribute to the submit buttonif ( $(event.target).attr("formnovalidate") !== undefined ) {validator.cancelSubmit = true;}});
  • 30. // validate the form on submitthis.submit( function( event ) {if ( validator.settings.debug ) {// prevent form submit to be able to see console outputevent.preventDefault();}function handle() {var hidden;if ( validator.settings.submitHandler ) {if ( validator.submitButton ) {// insert a hidden input as a replacement for the missing submit buttonhidden = $("<input type=hidden/>").attr("name", validator.submitButton.name).val( $(validator.submitButton).val() ).appendTo(validator.currentForm);}validator.settings.submitHandler.call( validator, validator.currentForm, event );if ( validator.submitButton ) {// and clean up afterwards; thanks to no-block-scope, hidden can be referencedhidden.remove();}return false;}return true;}// prevent submit for invalid forms or custom submit handlersif ( validator.cancelSubmit ) {validator.cancelSubmit = false;return handle();}if ( validator.form() ) {if ( validator.pendingRequest ) {validator.formSubmitted = true;return false;}return handle();} else {validator.focusInvalid();return false;}});}return validator;}
  • 31. 14 (FOURTEEN!) ifs
  • 32. function validate( options ) {// if nothing is selected, return nothing; cant chain anywayif ( !this.length ) {if ( options && options.debug && window.console ) {console.warn( "Nothing selected, cant validate, returning nothing." );}return;}// check if a validator for this form was already createdvar validator = $.data( this[0], "validator" );if ( validator ) {return validator;}// Add novalidate tag if HTML5.this.attr( "novalidate", "novalidate" );validator = new $.validator( options, this[0] );$.data( this[0], "validator", validator );if ( validator.settings.onsubmit ) {this.validateDelegate( ":submit", "click", function( event ) {if ( validator.settings.submitHandler ) {validator.submitButton = event.target;}// allow suppressing validation by adding a cancel class to the submit buttonif ( $(event.target).hasClass("cancel") ) {validator.cancelSubmit = true;}// allow suppressing validation by adding the html5 formnovalidate attribute to the submit buttonif ( $(event.target).attr("formnovalidate") !== undefined ) {validator.cancelSubmit = true;}});
  • 33. // validate the form on submitthis.submit( function( event ) {if ( validator.settings.debug ) {// prevent form submit to be able to see console outputevent.preventDefault();}function handle() {var hidden;if ( validator.settings.submitHandler ) {if ( validator.submitButton ) {// insert a hidden input as a replacement for the missing submit buttonhidden = $("<input type=hidden/>").attr("name", validator.submitButton.name).val( $(validator.submitButton).val() ).appendTo(validator.currentForm);}validator.settings.submitHandler.call( validator, validator.currentForm, event );if ( validator.submitButton ) {// and clean up afterwards; thanks to no-block-scope, hidden can be referencedhidden.remove();}return false;}return true;}// prevent submit for invalid forms or custom submit handlersif ( validator.cancelSubmit ) {validator.cancelSubmit = false;return handle();}if ( validator.form() ) {if ( validator.pendingRequest ) {validator.formSubmitted = true;return false;}return handle();} else {validator.focusInvalid();return false;}});}return validator;}
  • 34. are comments a bad thing?
  • 35. TIp #2Code should talk to you
  • 36. _$ = (function(_) {return {pub: function(a, b, c, d) {for (d=-1, c=[].concat(_[a]); c[++d];) c[d](b)},sub: function(a, b) {(_[a] || (_[a] = [])).push(b)}}})({})
  • 37. _$ = (function(_) {return {pub: function(a, b, c, d) {for (d=-1, c=[].concat(_[a]); c[++d];) c[d](b)},sub: function(a, b) {(_[a] || (_[a] = [])).push(b)}}})({})#140bytes
  • 38. _$ = (function() {var registered = {};return {pub: function(event, memo) {if (registered[event] instanceof Array){var handlers = [].concat(registered[event]);for (var i=0, handler; (handler = handlers[i]); i++){handler.call(this, memo);}}},sub: function(event, handler) {if (typeof registered[event] === "undefined"){registered[event] = [];}registered[event].push(handler);}};})();
  • 39. don’t use comments as anexcuse to write bad code
  • 40. //used translate3d to trigger hardware acceleration in webViews//http://www.youtube.com/watch?v=IKl78ZgJzm4.animated {translate: translate3d(0,0,0)}/*** Returns a unique ID for use in HTML id attribute.* @param {String/Number} nr A name or number of the ID.* @param {String} [prefix="id-"] The prefix for the ID.* @return {String} the new ID*/function createId(nr, prefix){//TODO implementation}
  • 41. //used translate3d to trigger hardware acceleration in webViews//http://www.youtube.com/watch?v=IKl78ZgJzm4.animated {translate: translate3d(0,0,0)}/*** Returns a unique ID for use in HTML id attribute.* @param {String/Number} nr A name or number of the ID.* @param {String} [prefix="id-"] The prefix for the ID.* @return {String} the new ID*/function createId(nr, prefix){//TODO implementation}un-avoidablehacks explanation
  • 42. //used translate3d to trigger hardware acceleration in webViews//http://www.youtube.com/watch?v=IKl78ZgJzm4.animated {translate: translate3d(0,0,0)}/*** Returns a unique ID for use in HTML id attribute.* @param {String/Number} nr A name or number of the ID.* @param {String} [prefix="id-"] The prefix for the ID.* @return {String} the new ID*/function createId(nr, prefix){//TODO implementation}un-avoidablehacks explanationAUTOMATED DOCGENERATION
  • 43. //used translate3d to trigger hardware acceleration in webViews//http://www.youtube.com/watch?v=IKl78ZgJzm4.animated {translate: translate3d(0,0,0)}/*** Returns a unique ID for use in HTML id attribute.* @param {String/Number} nr A name or number of the ID.* @param {String} [prefix="id-"] The prefix for the ID.* @return {String} the new ID*/function createId(nr, prefix){//TODO implementation}un-avoidablehacks explanationAUTOMATED DOCGENERATIONTODOs
  • 44. TIp #3Code should have boundaries
  • 45. Singleresponsibilityprincipleyour best toolagainst Zombie Codesince1902(guaranteed 20 years)
  • 46. No globalpollutionhttp://leosabanganii.blogspot.co.uk/2012/10/zombie-dressed-activists-protest.html
  • 47. No couplinghttp://leosabanganii.blogspot.co.uk/2012/10/zombie-dressed-activists-protest.htmlhttp://ajandcharli.blogspot.co.uk/2011/05/we-dont-do-dead-people.html
  • 48. worst case smell
  • 49. worst case smellLong methods
  • 50. worst case smellLong methodsDeep Level of Indentation
  • 51. worst case smellLong methodsDeep Level of IndentationHard to tell what it does
  • 52. worst case smellLong methodsDeep Level of IndentationHard to tell what it doesLack of portability
  • 53. worst case smellLong methodsDeep Level of IndentationHard to tell what it doesLack of portabilityHardcoded style/templating
  • 54. worst case smellLong methodsDeep Level of IndentationHard to tell what it doesLack of portabilityHardcoded style/templatingLogic block duplication
  • 55. worst case smellLong methodsDeep Level of IndentationHard to tell what it doesLack of portabilityHardcoded style/templatingLogic block duplicationCallback hell
  • 56. And now what?
  • 57. Play cool!
  • 58. BasicallyQuarantine
  • 59. BasicallyQuarantine
  • 60. QUARANTINEMost teams are trying to stop furtherspread only through quarantines. Its a goodshort-term solution, but it wont preventlong-term population loss.http://cdmx.it/quarantinequote
  • 61. The broken window
  • 62. “Dont leave "broken windows" (baddesigns, wrong decisions, or poor code)unrepaired. Fix each one as soon as it isdiscovered.”Programming is insanely detail oriented, and perhaps this is why:if youre not on top of the details, the perception is that thingsare out of control, and its only a matter of time before yourproject spins out of control. Maybe we should be sweating thesmall stuff.Jeff Atwoodhttp://www.codinghorror.com/blog/2005/06/the-broken-window-theory.htmlThe broken window
  • 63. Maybe we should be sweatingthe small stuff.Jeff Atwoodhttp://www.codinghorror.com/blog/2005/06/the-broken-window-theory.htmlThe broken window
  • 64. Isolate the Zombies
  • 65. define style guidelines
  • 66. function Zombie(personName){function do_something() {console.log(personName + " just ate a brain!");}return {doSomethingZombiesDo: do_something};}var adam = new Zombie("Adam");adam.doSomethingZombiesDo();
  • 67. function Zombie(personName){function do_something() {console.log(personName + " just ate a brain!");}return {doSomethingZombiesDo: do_something};}var adam = new Zombie("Adam");adam.doSomethingZombiesDo();
  • 68. function Zombie(personName){function do_something() {console.log(personName + " just ate a brain!");}return {doSomethingZombiesDo: do_something};}var adam = new Zombie("Adam");adam.doSomethingZombiesDo();
  • 69. function Zombie(personName){function do_something() {console.log(personName + " just ate a brain!");}return {doSomethingZombiesDo: do_something};}var adam = new Zombie("Adam");adam.doSomethingZombiesDo();
  • 70. define style guidelines
  • 71. start linting your code
  • 72. Inversion of control freaknessAM I A CONTROL FREAK?
  • 73. start testing your code
  • 74. Unit or Functional?
  • 75. Do both
  • 76. What to testUnit testing issupposed to test asingle atomic “unit” offunctionality withoutdependencies onanything else
  • 77. What to testUnit testing issupposed to test asingle atomic “unit” offunctionality withoutdependencies onanything elseThis is where you startto run into seriousdependency problemsdue to the interrelationHTML and CSS
  • 78. What to testUnit testing issupposed to test asingle atomic “unit” offunctionality withoutdependencies onanything elseThis is where you startto run into seriousdependency problemsdue to the interrelationHTML and CSSWhat do you test?Usually how the userinterface responds touser input.Actually, the realm offunctional testing
  • 79. No matter which toolsetGruntPhantomJSJsTestDriverBuster.jsKarmaChutzpahTestemQunitMochaJasmine
  • 80. No matter which toolsetGruntPhantomJSJsTestDriverBuster.jsKarmaChutzpahTestemQunitMochaJasmine
  • 81. As long as it can be automatedshareidentifybuildmake itcontinuous
  • 82. Make it part of the processMake it part of the process
  • 83. Make it part of the processhttp://rosarioconsulting.net/inspiredtoeducate/?p=706 http://powerbuilder.us/Estimate testinghttp://malyn.edublogs.org/2011/10/16/process-tools-people/
  • 84. Make it part of the processDo code reviewhttp://rosarioconsulting.net/inspiredtoeducate/?p=706 http://powerbuilder.us/http://malyn.edublogs.org/2011/10/16/process-tools-people/
  • 85. Make it part of the processhttp://rosarioconsulting.net/inspiredtoeducate/?p=706 http://powerbuilder.us/Involve peoplehttp://malyn.edublogs.org/2011/10/16/process-tools-people/
  • 86. Fear the living? DON’T
  • 87. The team
  • 88. DEVOPS PRODUCT OWNERqa
  • 89. QA
  • 90. QACrucial role in theprocess
  • 91. QACrucial role in theprocessQuality should be yourgoal too
  • 92. QACrucial role in theprocessQuality should be yourgoal tooGet help for functionaltest coverage not toscrew up refactoring
  • 93. Devops
  • 94. DevopsThe tough guy
  • 95. DevopsThe tough guyIt could be hard to dealwith
  • 96. DevopsThe tough guyIt could be hard to dealwithGet help setting up theautomated process
  • 97. Product owner
  • 98. Product ownerThe less interested incode itself
  • 99. Product ownerThe less interested incode itselfBring numbers, nottheories
  • 100. Product ownerThe less interested incode itselfBring numbers, nottheoriesGet help not wastingtime, staying focused onfunctionalities
  • 101. Others in the team
  • 102. juniorsexternallobbyist
  • 103. Juniors
  • 104. JuniorsPair with them, codereview their (and your)code
  • 105. JuniorsPair with them, codereview their (and your)codeInvolve them during thewhole process definition
  • 106. JuniorsPair with them, codereview their (and your)codeInvolve them during thewhole process definitionGet help keeping thingseasy and accessible
  • 107. Lobbyists
  • 108. LobbyistsThey will slow youdown, your brain will bemore prone to be eaten
  • 109. LobbyistsThey will slow youdown, your brain will bemore prone to be eatenRedirect them to theproduct owner
  • 110. BasicallyKILL ‘EM ALL (AGAIN?)
  • 111. BasicallyKILL ‘EM ALL (AGAIN?)
  • 112. KILL ‘EM ALL (AGAIN?)“Nothing is impossible to kill.”Mira Grant, Feed
  • 113. but
  • 114. “Without requirements or design,programming is the art of adding bugsto an empty text file”Louis SrygleyDesign for your goal
  • 115. Design for your goal
  • 116. Modular Architecture
  • 117. Scalable JavaScriptApplicationArchitectureby Nicholas Zakas
  • 118. core.register("module-name", function(sandbox){return {init:function(){},destroy:function(){}};});
  • 119. core.register("module-name", function(sandbox){return {init:function(){},destroy:function(){}};});
  • 120. core.register("module-name", function(sandbox){return {init:function(){},destroy:function(){}};});
  • 121. core.register("module-name", function(sandbox){return {init:function(){var user = sandbox.getUser();},destroy:function(){}};});
  • 122. core.register("module-name", function(sandbox){return {init:function(){var user = sandbox.getUser();},destroy:function(){}};});
  • 123. core.register(module-name, function(sandbox){return {init:function(config){console.log(config.id);}};});core.configure(module-name, {id: container,});core.start(module-name);core.stop(module-name);
  • 124. core.register(module-name, function(sandbox){return {init:function(config){console.log(config.id);}};});core.configure(module-name, {id: container,});core.start(module-name);core.stop(module-name);
  • 125. core.register(module-name, function(sandbox){return {init:function(config){console.log(config.id);}};});core.configure(module-name, {id: container,});core.start(module-name);core.stop(module-name);
  • 126. core.register(module-name, function(sandbox){return {init:function(config){console.log(config.id);}};});core.configure(module-name, {id: container,});core.start(module-name);core.stop(module-name);
  • 127. core.register(module-name, function(sandbox){return {init:function(config){console.log(config.id);}};});core.configure(module-name, {id: container,});core.start(module-name);core.stop(module-name);
  • 128. core.register(module-name, function(sandbox){return {init:function(config){console.log(config.id);}};});core.configure(module-name, {id: container,});core.start(module-name);core.stop(module-name);
  • 129. Event Driven Pattern
  • 130. core.register("module-name", function(sandbox){return {init: function(){sandbox.layer("an error occured");}};});
  • 131. core.register("module-name", function(sandbox){return {init: function(){sandbox.layer("an error occured");}};});
  • 132. sandbox.layer("an error occured");
  • 133. sandbox.publish("error", {msg: "an error occured"});
  • 134. sandbox.publish("error", {msg: "an error occured"});core.register("errManager", function(sandbox){return {init: function(){sandbox.subscribe("error", function(err) {console.log(err.msg)});}};});
  • 135. sandbox.publish("error", {msg: "an error occured"});core.register("errManager", function(sandbox){return {init: function(){sandbox.subscribe("error", function(err) {console.log(err.msg)});}};});
  • 136. sandbox.publish("error", {msg: "an error occured"});core.register("errManager", function(sandbox){return {init: function(){sandbox.subscribe("error", function(err) {console.log(err.msg)});}};});
  • 137. sandbox.publish("error", {msg: "an error occured"});core.register("errManager", function(sandbox){return {init: function(){sandbox.subscribe("error", function(err) {console.log(err.msg)});}};});
  • 138. sandbox.publish("error", {msg: "an error occured"});core.register("errManager", function(sandbox){return {init: function(){sandbox.subscribe("error", function(err) {console.log(err.msg)});}};});
  • 139. sandbox.publish("error", {msg: "an error occured"});core.register("errManager", function(sandbox){return {init: function(){sandbox.subscribe("error", function(err) {console.log(err.msg)});}};});
  • 140. sandbox.publish("error", {msg: "an error occured"});core.register("errManager", function(sandbox){return {init: function(){sandbox.subscribe("error", function(err) {console.log(err.msg)});}};});
  • 141. sandbox.publish("error", {msg: "an error occured"});core.register("errManager", function(sandbox){return {init: function(){sandbox.subscribe("error", function(err) {console.log(err.msg)});}};});
  • 142. sandbox.subscribe("error", function(payload){console.log(payload.msg);});Advantages
  • 143. sandbox.subscribe("error", function(payload){console.log(payload.msg);});AdvantagesSEMANTIC
  • 144. sandbox.subscribe("error", function(payload){console.log(payload.msg);});AdvantagesSEMANTICflexibility
  • 145. AdvantagesDECOUPLING
  • 146. “The key is to acknowledge from thestart that you have no idea how this willgrow.When you accept that you don’tknow everything, you begin to designthe system defensively.”Nicholas ZakasOverengineering?
  • 147. AMD
  • 148. icon by http://www.deleket.com/jQueryMustacheLibraries Plugins Your scripts
  • 149. icon by http://www.deleket.com/jQueryMustacheLibraries Plugins Your scripts
  • 150. <script src="jquery.min.js"></script><script src="mustache.js"></script><?php if ($env == "prod") : ?><script src="my-code-bundle.js"></script><?php else: ?><script src="jquery.plugin_1.js"></script><script src="jquery.plugin_2.js"></script><script src="my-code_1.js"></script><script src="my-code_2.js"></script><script src="my-code_3.js"></script><script src="my-code_4.js"></script><script src="my-code_5.js"></script><?php endif; ?>
  • 151. var MyNamespace = {};MyNamespace.MyAwesomeLibrary = function() {//implementation};MyNamespace.AnotherCoolOne = function() {//implementation};MyNamespace.SlightlyCrappyLibrary = function() {//implementation};MyNamespace.BestLibEver = function() {//implementation};
  • 152. //API: define(id?, dependencies?, factory);define("My-Module", ["Another-Module"], function(AnotherModule){// Do Something});one define to rule them all
  • 153. //API: define(id?, dependencies?, factory);define("My-Module", ["Another-Module"], function(AnotherModule){// Do Something});one define to rule them all
  • 154. //app/config.jsdefine([], function() {return {url: "http://whatever.it/is/",debug: true};});
  • 155. //app/config.jsdefine([], function() {return {url: "http://whatever.it/is/",debug: true};});//app/config.jsdefine({url: "http://whatever.it/is/",debug: true});
  • 156. //app/config.jsdefine([], function() {return {url: "http://whatever.it/is/",debug: true};});//app/config.jsdefine({url: "http://whatever.it/is/",debug: true});
  • 157. //app/config.jsdefine([], function() {return {url: "http://whatever.it/is/",debug: true};});//app/config.jsdefine({url: "http://whatever.it/is/",debug: true});
  • 158. //app/myProduct.jsdefine(["app/config"], function(config) {return function(id){return {getProductUrl: function(){var prodPath = config.url + "product/" + id;if (config.debug){console.log(prodPath)}return prodPath;}};};});
  • 159. //app/myProduct.jsdefine(["app/config"], function(config) {return function(id){return {getProductUrl: function(){var prodPath = config.url + "product/" + id;if (config.debug){console.log(prodPath)}return prodPath;}};};});
  • 160. //app/myProduct.jsdefine(["app/config"], function(config) {return function(id){return {getProductUrl: function(){var prodPath = config.url + "product/" + id;if (config.debug){console.log(prodPath)}return prodPath;}};};});
  • 161. //app/myProduct.jsdefine(["app/config"], function(config) {return function(id){return {getProductUrl: function(){var prodPath = config.url + "product/" + id;if (config.debug){console.log(prodPath)}return prodPath;}};};});
  • 162. //app/myProduct.jsdefine(["app/config"], function(config) {return function(id){return {getProductUrl: function(){var prodPath = config.url + "product/" + id;if (config.debug){console.log(prodPath)}return prodPath;}};};});
  • 163. //app/myProduct.jsdefine(["app/config"], function(config) {return function(id){return {getProductUrl: function(){var prodPath = config.url + "product/" + id;if (config.debug){console.log(prodPath)}return prodPath;}};};});
  • 164. //app/myProduct.jsdefine(["app/config"], function(config) {return function(id){return {getProductUrl: function(){var prodPath = config.url + "product/" + id;if (config.debug){console.log(prodPath)}return prodPath;}};};});
  • 165. //app/myProduct.jsdefine(["app/config"], function(config) {return function(id){return {getProductUrl: function(){var prodPath = config.url + "product/" + id;if (config.debug){console.log(prodPath)}return prodPath;}};};});
  • 166. //app/myProduct.jsdefine(["app/config"], function(config) {return function(id){return {getProductUrl: function(){var prodPath = config.url + "product/" + id;if (config.debug){console.log(prodPath)}return prodPath;}};};});
  • 167. <script data-main="app/main" src="require.js"></script>
  • 168. <script data-main="app/main" src="require.js"></script>//app/main.jsrequire(["jQuery", "app/myProduct"], function($, Product) {$(".product").on("click", function(){var prodID = $(this).data("id");var prod = new Product(prodID);document.location.href = prod.getProductUrl();})});
  • 169. <script data-main="app/main" src="require.js"></script>//app/main.jsrequire(["jQuery", "app/myProduct"], function($, Product) {$(".product").on("click", function(){var prodID = $(this).data("id");var prod = new Product(prodID);document.location.href = prod.getProductUrl();})});
  • 170. <script data-main="app/main" src="require.js"></script>//app/main.jsrequire(["jQuery", "app/myProduct"], function($, Product) {$(".product").on("click", function(){var prodID = $(this).data("id");var prod = new Product(prodID);document.location.href = prod.getProductUrl();})});
  • 171. <script data-main="app/main" src="require.js"></script>//app/main.jsrequire(["jQuery", "app/myProduct"], function($, Product) {$(".product").on("click", function(){var prodID = $(this).data("id");var prod = new Product(prodID);document.location.href = prod.getProductUrl();})});
  • 172. <script data-main="app/main" src="require.js"></script>//app/main.jsrequire(["jQuery", "app/myProduct"], function($, Product) {$(".product").on("click", function(){var prodID = $(this).data("id");var prod = new Product(prodID);document.location.href = prod.getProductUrl();})});
  • 173. Pulling all together
  • 174. define(function(){use strict;return function(sandbox){//the logic of the modulefunction doSomething(){//do something}return {init: function(config){//the initialization codesandbox.subscribe(myEventName, doSomething)},destroy: function(){//optional destroy method}};};});
  • 175. define(function(){use strict;return function(sandbox){//the logic of the modulefunction doSomething(){//do something}return {init: function(config){//the initialization codesandbox.subscribe(myEventName, doSomething)},destroy: function(){//optional destroy method}};};});
  • 176. define(function(){use strict;return function(sandbox){//the logic of the modulefunction doSomething(){//do something}return {init: function(config){//the initialization codesandbox.subscribe(myEventName, doSomething)},destroy: function(){//optional destroy method}};};});
  • 177. define(function(){use strict;return function(sandbox){//the logic of the modulefunction doSomething(){//do something}return {init: function(config){//the initialization codesandbox.subscribe(myEventName, doSomething)},destroy: function(){//optional destroy method}};};});
  • 178. define(function(){use strict;return function(sandbox){//the logic of the modulefunction doSomething(){//do something}return {init: function(config){//the initialization codesandbox.subscribe(myEventName, doSomething)},destroy: function(){//optional destroy method}};};});
  • 179. require(["akase"], function(core) {core.start("module1");core.start("module2", {config: {debug: true}});core.start("module3", { event: "audio:stop" });});
  • 180. require(["akase"], function(core) {core.start("module1");core.start("module2", {config: {debug: true}});core.start("module3", { event: "audio:stop" });});
  • 181. require(["akase"], function(core) {core.start("module1");core.start("module2", {config: {debug: true}});core.start("module3", { event: "audio:stop" });});
  • 182. require(["akase"], function(core) {core.start("module1");core.start("module2", {config: {debug: true}});core.start("module3", { event: "audio:stop" });});
  • 183. require(["akase"], function(core) {core.start("module1");core.start("module2", {config: {debug: true}});core.start("module3", { event: "audio:stop" });});
  • 184. ākāśesanskrit for "in the sky"/"to the sky"https://github.com/cedmax/akase
  • 185. No such thing!
  • 186. BasicallyHappy Endings?
  • 187. BasicallyHappy Endings?
  • 188. “If you want a happy ending, thatdepends, of course, on where you stopyour story.”OrsonWellsHappy ending
  • 189. You can run, you can hide
  • 190. You are going toSHITTY codeanywaywrite
  • 191. faceYou are going toSHITTY codeanyway
  • 192. faceYou are going toZombie codeanyway
  • 193. Embrace it!http://drezner.foreignpolicy.com/posts/2009/08/18/theory_of_international_politics_and_zombies
  • 194. Don’t improvise
  • 195. Learn to know how to dealwith it
  • 196. Until you master it
  • 197. in any case justremember to
  • 198. Aim for the headhttp://halloween.squidoo.com/get-spooked/aim-for-the-head
  • 199. marco@fromthefront.ithttp://cedmax.com@cedmaxany question?

×