Slide 1

Slide 1 text

DASHBOARD

Slide 2

Slide 2 text

● Transparent: The consequences of change should be obvious in the code that is changing and in distant code that relies upon it. ● Reasonable: The cost of any change should be proportional to the benefits the change achieves ● Usable: Existing code should be usable in new and unexpected contexts ● Exemplary: The code itself should encourage those who change it to perpetuate these qualities. T.R.U.E. CODE http://www.poodr.com/

Slide 3

Slide 3 text

“Fuck design patterns” “I don’t know. I just copied it.” “Is it bad, or is it you didn't write it?” CLASSIC

Slide 4

Slide 4 text

The code itself should encourage those who change it to perpetuate these qualities. EXEMPLARY CODE http://randycoulman.com/blog/2013/04/09/exemplary-code/

Slide 5

Slide 5 text

VS

Slide 6

Slide 6 text

ANTI-DESIGN Design: making guesses about unknown requirements and writing speculative code in an attempt to preemptively meet them. Design == Over-Design PRO-DESIGN Design: the current arrangement of an application’s code Act of Design: using one’s knowledge of the consequences of various code arrangement techniques to solve the current problem in a way that accommodates the next (as yet undefined) change. “These disputes are not about core beliefs, they merely reflect a communication gap.” http://www.sandimetz.com/blog/2012/07/05/how-shall-we-define-design/

Slide 7

Slide 7 text

“ERGONOMICS FOR YOUR MIND”

Slide 8

Slide 8 text

REDUCE DUPLICATION apiUser: (path='', data={}, method='GET', callback) -> start = new Date().getTime() # … param munging omitted parameters = user: app.settings.user path: path unless _.isUndefined(data) or _.isFunction(data) parameters.data = data log.debug 'REQ', "#{method} user/#{path}", parameters request(method, '/pp.php') .send(parameters) .end((res) => log.debug 'RES', "#{method} user/#{path}", res # If the response has a 5xx status code, record this. if res.status >= 500 recordAPIFail(method, path, data, res) # Record how long the api request took. app.util.apiTiming(path, new Date().getTime() - start) if res.status >= 400 if res.body? error = res.body else error = res.status else error = null if _.isFunction callback return callback error, res.body, res ) makeSiteApiFunction: (siteId) -> return (path='', data={}, method = 'GET') -> start = new Date().getTime() # … param munging omitted parameters = site: siteId path: path unless _.isUndefined(data) or _.isFunction(data) parameters.data = data log.debug 'REQ', "#{method} site/#{path}", parameters request(method, '/pp.php') .send(parameters) .end((res) => log.debug 'RES', "#{method} site/#{path}", res # Record how long the api request took. app.util.apiTiming(path, new Date().getTime() - start) # If the response has a 5xx status code, record this. if res.status >= 500 recordAPIFail(method, path, data, res) if res.status >= 400 error = res.status else error = null if _.isFunction callback return callback error, res.body, res ) memoized different param slightly different error checking code same code, different order

Slide 9

Slide 9 text

LISKOV SUBSTITUTION “User.what?” PRINCIPLE OF LEAST ASTONISHMENT

Slide 10

Slide 10 text

MODULARITY window.app.util.analyticsTrack() window.app.util.userGet() window.app.util.userSet() window.app.util.makeSiteApi() window.app.util.apiUser() window.app.util.sendGraphite() window.app.util.getGravatar() window.app.util.apiTiming() window.app.util.getAccentColor() window.app.util.featureEnabled() window.app.util.parseSize() window.app.util.uuidFromEmail() window.app.util.createCSVDownload() window.app.util.isOnebox() window.app.util.validateEmail() window.app.util.pardotTrack()

Slide 11

Slide 11 text

LAW OF DEMETER @site.collections.environments.get(workshop.get('workspace'))?.isBranch() app.me.get('organizations')?[app.ws.models.site.get('organization').organization]?.admin "

#{ if app.ws.models.site.get('upstream')?.branch? then app.ws.models.site.get ('upstream')?.branch else 'master' }

"

Slide 12

Slide 12 text

HTML Poking Form-data Munging Updating Models/Collections Making API Calls SINGLE RESPONSIBILITY

Slide 13

Slide 13 text

SINGLE RESPONSIBILITY

Slide 14

Slide 14 text

Do (not “must”) Don’t (not “can’t”) Dependencies are injected or required() Access window.app deep in methods Export singletons Attach to window.app view.render() is idempotent View.render() appends to html API calls happen on models/collections Make API calls in View Use templates Concat/$.append html strings in Views Inject primitive values into templates Inject fat objects/models into templates Assign @options.property to @property in #initialize Access @options.property deep in other methods initialize() doesn't have side effects such as auto- render Make api calls in initialize or call render() Views should listen to model state and re-render Use jQuery to modify specific elements on events DASHBOARD EPIC

Slide 15

Slide 15 text

Javascript MVC Styleguide http://blhttp://blog.sourcing.io/mvc-style-guideog.sourcing.io/mvc- style-guide Backbone Anti-Patterns http://blog.shinetech.com/2013/11/26/backbone-antipatterns/