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

Optimizing for Developer Delight

Optimizing for Developer Delight

JSConf 2013

Earlier this year, I sat down with 25,000 lines of code written by a team of variously experienced developers in the crucible of a non-negotiable deadline. I didn't have a list of features to add or a list of bugs to fix; my mandate, as more and more developers were trying and struggling to contribute to the project, was to focus on developer happiness. From simple improvements like adding asserts and logging, to major changes that touched a scary-large portion of the repo, this talk will take a look at what we did to make a large codebase easier to understand, what we still need to do, and what you should start doing on your own project as soon as you get back to work.

0177cdce6af15e10db15b6bf5dc4e0b0?s=128

Rebecca Murphey

May 29, 2013
Tweet

Transcript

  1. Optimizing for Developer Delight Rebecca Murphey • JSConf 2013 Wednesday,

    May 29, 13
  2. @rmurphey • rmurphey.com bazaarvoice.com Wednesday, May 29, 13

  3. @rmurphey • rmurphey.com bazaarvoice.com Wednesday, May 29, 13

  4. • large and growing codebase • mission-critical application • constantly

    expanding team • mix of junior and senior devs • mandate for rapid feature development the problem Wednesday, May 29, 13
  5. • a clear path for getting up to speed •

    points of entry for junior & senior devs • as few surprises as possible: it just works • isolated complexity • easy development and debugging • nothing more difficult than it “should” be “developer delight” Wednesday, May 29, 13
  6. assert all the things Wednesday, May 29, 13

  7. Wednesday, May 29, 13

  8. BVReporter.assert(    _(config).isObject(),      'config  is  object' ); BVReporter.assert(

       !_(config.subjectId).isUndefined(),      'config.subjectId  is  defined' ); Wednesday, May 29, 13
  9. assert  :  function  (assertion,  message)  {    if  (!assertion)  {

           throw  new  Error('Assertion  failed:  '  +  message);    } } Wednesday, May 29, 13
  10. lifecycle logging log the lifecycle Wednesday, May 29, 13

  11. Wednesday, May 29, 13

  12. BVReporter.group(BVReporter.INFO,  'Component  Initialization'); _(componentData).each(function  (cd,  componentName)  {    var  c

     =  new  BComponent(cd);    this.components[componentName]  =  c; },  this); BVReporter.groupEnd(BVReporter.INFO,  'Component  Initialization'); Wednesday, May 29, 13
  13. Wednesday, May 29, 13

  14. eliminate temptation Wednesday, May 29, 13

  15. define([    'ENV',    'underscore',    'bv/api/fetch' ],  function  (ENV,

     _,  api)  { Wednesday, May 29, 13
  16. ENV.trigger('showLoading'); Wednesday, May 29, 13

  17. ENV.trigger(    'track:error',      new  Error('Missing  parent  in  Collection

     :  '  +  this.name) ); Wednesday, May 29, 13
  18. ENV.trigger('track:conversion',  data,  conversion); Wednesday, May 29, 13

  19. if  (      !ENV.get('userTokenDfd')  ||      ENV.get('userTokenDfd').state()  ===

     'resolved' )  {    ENV.set({  userTokenDfd  :  $.Deferred()  }); } Wednesday, May 29, 13
  20. this.on('pageto',  this.fetchPage,  ENV); Wednesday, May 29, 13

  21. ENV.trigger('showLoading'); LoadingOverlay.show(); Wednesday, May 29, 13

  22. ENV.trigger(    'track:error',      new  Error('Missing  parent  in  Collection

     :  '  +  this.name) ); BVTracker.error(  new  Error(        'Missing  parent  in  Collection  :  '  +  this.name )  ); ENV.trigger('track:conversion',  data,  conversion); BVTracker.conversion(data,  conversion); Wednesday, May 29, 13
  23. this.on('pageto',  this.fetchPage,  ENV); this.subscribe('pageto',  this.fetchPage); Wednesday, May 29, 13

  24. code for every concept Wednesday, May 29, 13

  25. ENV.trigger(    'track:error',      new  Error('Missing  parent  in  Collection

     :  '  +  this.name) ); BVTracker.error(  new  Error(        'Missing  parent  in  Collection  :  '  +  this.name )  ); Wednesday, May 29, 13
  26. "reviewContentList"  :  {    "features"  :  {      

     "self"  :  ["headToHead",  "contentFilter",  "contentItemCo        "contentItem"  :  ["has:stars",  "has:secondaryRatings",  "        "pagination"  :  ["ugcCount"],        "secondaryContentList"  :  ["secondaryContentItemCollecti        "secondaryContentItem"  :  ["avatar",  "feedback"],        "contentFilter"  :  ["has:filterButton"]    },    //  ... }, Wednesday, May 29, 13
  27. var  components  =  ENV.get('components'); components.each(function  (component,  index)  {    var

     view  =  init.initView(component,  index);    //  ... }); Wednesday, May 29, 13
  28. Wednesday, May 29, 13

  29. _(componentData).each(function  (config,  componentName)  {    var  c  =  new  Component(config);

       this.components[componentName]  =  c;    var  view  =  c.initView(index);    //  ... },  this); Wednesday, May 29, 13
  30. automate everything Wednesday, May 29, 13

  31. Wednesday, May 29, 13

  32. Wednesday, May 29, 13

  33. Wednesday, May 29, 13

  34. document Wednesday, May 29, 13

  35. Wednesday, May 29, 13

  36. Wednesday, May 29, 13

  37. Wednesday, May 29, 13

  38. Wednesday, May 29, 13

  39. Wednesday, May 29, 13

  40. Wednesday, May 29, 13

  41. Wednesday, May 29, 13

  42. measure progress (and side effects) Wednesday, May 29, 13

  43. Wednesday, May 29, 13

  44. Wednesday, May 29, 13

  45. “I wish I’d had this documentation when I was building

    that feature last week.” “So I can just add my own logging and they’ll show up in these groups automatically?” “e assertion stuff just caught an error in my code that I would have missed.” Wednesday, May 29, 13
  46. are we there yet? Wednesday, May 29, 13

  47. @rmurphey • rmurphey.com bazaarvoice.com Wednesday, May 29, 13