building rich user experiences without javascript spaghetti

85
Building Rich User Experiences without JavaScript Spaghetti by Jared Faris @jaredthenerd jaredthenerd.com Friday, June 29, 12

Upload: jared-faris

Post on 13-May-2015

2.192 views

Category:

Technology


0 download

DESCRIPTION

Given at MADExpo 2012Most Javascript is written to glue code and UI together without any thought to design patterns. Over time this leads to piles of Javascript that look nothing like code you’d be proud of writing. In this talk we’ll look at the rise of software libraries (like Knockout) that can help add structure to your JS. We’ll talk about when they help your project, and when they get in the way. We’ll also look into how you can easily use the Mediator and Observer patterns in JavaScript to really clean up your code with or without other libraries. As an added bonus we’ll talk about using Message Buses to really decouple your JavaScript controls. I’ll explain how we’re using these patterns at Facio and how you can implement them in your code. At the end we'll look at some code samples and we'll talk about whatever other patterns you might be interested in doing in JavaScript.

TRANSCRIPT

Page 1: Building Rich User Experiences Without JavaScript Spaghetti

Building Rich User Experienceswithout

JavaScript Spaghetti

by Jared Faris@jaredthenerd

jaredthenerd.com

Friday, June 29, 12

Page 2: Building Rich User Experiences Without JavaScript Spaghetti

About me

Friday, June 29, 12

Page 3: Building Rich User Experiences Without JavaScript Spaghetti

Designers

Friday, June 29, 12

Page 4: Building Rich User Experiences Without JavaScript Spaghetti

Developers

Friday, June 29, 12

Page 5: Building Rich User Experiences Without JavaScript Spaghetti

JavaScript

Friday, June 29, 12

Page 6: Building Rich User Experiences Without JavaScript Spaghetti

A Developer’s Problem

Developers are the only people in the organization that wear every single hat.

Building a great user experience is hard.

It’s even harder to build them so that they cangrow painlessly.

Friday, June 29, 12

Page 7: Building Rich User Experiences Without JavaScript Spaghetti

Problem (part 2)

JavaScript lends itself very well to building really horrible code that doesn’t scale. At all. Ever.

Friday, June 29, 12

Page 8: Building Rich User Experiences Without JavaScript Spaghetti

A Typical Product LifecycleSomewhat dramatized...

Friday, June 29, 12

Page 9: Building Rich User Experiences Without JavaScript Spaghetti

Designer Developer

Friday, June 29, 12

Page 10: Building Rich User Experiences Without JavaScript Spaghetti

We need this feature

Friday, June 29, 12

Page 11: Building Rich User Experiences Without JavaScript Spaghetti

I got this

Friday, June 29, 12

Page 12: Building Rich User Experiences Without JavaScript Spaghetti

?

Friday, June 29, 12

Page 13: Building Rich User Experiences Without JavaScript Spaghetti

Tweaking time...

Friday, June 29, 12

Page 14: Building Rich User Experiences Without JavaScript Spaghetti

I got anothergreat idea

Friday, June 29, 12

Page 15: Building Rich User Experiences Without JavaScript Spaghetti

Now you tellme

Friday, June 29, 12

Page 16: Building Rich User Experiences Without JavaScript Spaghetti

The developer bolts on some more code

Friday, June 29, 12

Page 17: Building Rich User Experiences Without JavaScript Spaghetti

And anotherthing...

Friday, June 29, 12

Page 18: Building Rich User Experiences Without JavaScript Spaghetti

grrr

Friday, June 29, 12

Page 19: Building Rich User Experiences Without JavaScript Spaghetti

We don’t ‘really’

need this

Friday, June 29, 12

Page 20: Building Rich User Experiences Without JavaScript Spaghetti

Uh, yeah wedo

Friday, June 29, 12

Page 21: Building Rich User Experiences Without JavaScript Spaghetti

Friday, June 29, 12

Page 22: Building Rich User Experiences Without JavaScript Spaghetti

The developer bolts on some more code

Friday, June 29, 12

Page 23: Building Rich User Experiences Without JavaScript Spaghetti

Some time passes

‘Some time’ is defined as: Just long enough that the developer doesn’t remember

exactly how his original code works.

Friday, June 29, 12

Page 24: Building Rich User Experiences Without JavaScript Spaghetti

I’ve got a new feature

Friday, June 29, 12

Page 25: Building Rich User Experiences Without JavaScript Spaghetti

Angry developerscan really do this.IT managers be

warned.

Friday, June 29, 12

Page 26: Building Rich User Experiences Without JavaScript Spaghetti

Protective Beret

Friday, June 29, 12

Page 27: Building Rich User Experiences Without JavaScript Spaghetti

More messy code

Friday, June 29, 12

Page 28: Building Rich User Experiences Without JavaScript Spaghetti

The last bug

Oh wait, one more

Friday, June 29, 12

Page 29: Building Rich User Experiences Without JavaScript Spaghetti

Finally

Friday, June 29, 12

Page 30: Building Rich User Experiences Without JavaScript Spaghetti

The next day...

Friday, June 29, 12

Page 31: Building Rich User Experiences Without JavaScript Spaghetti

Friday, June 29, 12

Page 32: Building Rich User Experiences Without JavaScript Spaghetti

Two weeks pass.

Friday, June 29, 12

Page 33: Building Rich User Experiences Without JavaScript Spaghetti

I’ve got a new feature Gahh!

Friday, June 29, 12

Page 34: Building Rich User Experiences Without JavaScript Spaghetti

Friday, June 29, 12

Page 35: Building Rich User Experiences Without JavaScript Spaghetti

No developers were harmed in the makingof this dramatic reenactment.

Friday, June 29, 12

Page 36: Building Rich User Experiences Without JavaScript Spaghetti

Additional Features + Short Sighted Architecting= Horrible JavaScript Spaghetti

Friday, June 29, 12

Page 37: Building Rich User Experiences Without JavaScript Spaghetti

Why does this happen?

This is where you earn audience participation points.

Friday, June 29, 12

Page 38: Building Rich User Experiences Without JavaScript Spaghetti

Some Reasons

• JavaScript isn’t real code• We don’t treat client side things as real features• We can’t easily test it• We don’t like writing it• It behaves differently in different browsers

Friday, June 29, 12

Page 39: Building Rich User Experiences Without JavaScript Spaghetti

This really all boils down to one thing.

We developers suck at JavaScript.

Friday, June 29, 12

Page 40: Building Rich User Experiences Without JavaScript Spaghetti

Three JavaScript Principles

• Decouple everything• Make it testable• Push events, not state

Friday, June 29, 12

Page 41: Building Rich User Experiences Without JavaScript Spaghetti

Decouple Everything

Start thinking about UI pieces as individual JS objects.Remove dependencies between objects.Apply your OO best practices here too.

Friday, June 29, 12

Page 42: Building Rich User Experiences Without JavaScript Spaghetti

Make It Testable

Separate DOM dependent stuff into a single layer.Put the rest of the stuff in classes that you can test.

Friday, June 29, 12

Page 43: Building Rich User Experiences Without JavaScript Spaghetti

Push Events, Not State

Know about the Law of Demeter.Let controls worry about their own state.

Inform other controls that “X happened to Y”, not “Y is in X state”

Friday, June 29, 12

Page 44: Building Rich User Experiences Without JavaScript Spaghetti

Some Patterns

Friday, June 29, 12

Page 45: Building Rich User Experiences Without JavaScript Spaghetti

OO

• Think in terms of classes• Give behaviors to objects• Keep state inside of objects

Friday, June 29, 12

Page 46: Building Rich User Experiences Without JavaScript Spaghetti

Mediator Pattern

"The essence of the Mediator Pattern is to "Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you

vary their interaction independently."

-Design Patterns: Elements of Reusable Object-Oriented Software

Friday, June 29, 12

Page 47: Building Rich User Experiences Without JavaScript Spaghetti

NavControlMediator

itemSelected()

Events from some other object

unselectAll()

Friday, June 29, 12

Page 48: Building Rich User Experiences Without JavaScript Spaghetti

Observer Pattern

"Define a one-to-many dependency between objects so that when one object changes state, all its dependents

are notified and updated automatically."

-Design Patterns: Elements of Reusable Object-Oriented Software

Think jQuery $(‘.something’).click()

Friday, June 29, 12

Page 49: Building Rich User Experiences Without JavaScript Spaghetti

NavControlMediator

itemSelected()

Events from some other object

unselectAll()

viewModel

Friday, June 29, 12

Page 50: Building Rich User Experiences Without JavaScript Spaghetti

Knockout.js Template Example

Friday, June 29, 12

Page 51: Building Rich User Experiences Without JavaScript Spaghetti

Pub/Sub + Fairy Dust = Service Bus

Pub/Sub is great to make sure events propagate.It starts to get brittle with lots of different controls.

Friday, June 29, 12

Page 52: Building Rich User Experiences Without JavaScript Spaghetti

Way Too Much Pubbing and Subbing

Friday, June 29, 12

Page 53: Building Rich User Experiences Without JavaScript Spaghetti

Service Bus

A service bus is another layer that sits outside controls.Controls that want to communicate speak through it.Your controls are then only coupled to a single thing.

Friday, June 29, 12

Page 54: Building Rich User Experiences Without JavaScript Spaghetti

Postal.js

Friday, June 29, 12

Page 55: Building Rich User Experiences Without JavaScript Spaghetti

Service Bus + Mediator

• Controls no longer need to know about others.• We can remove/replace controls individually.• We can add controls that listen to the same events without modifying the publisher.• We can re-use pieces more easily because they work in a standard way.

Friday, June 29, 12

Page 56: Building Rich User Experiences Without JavaScript Spaghetti

NavControlMediator

itemSelected()

Events from some other object

unselectAll()

viewModel

ReportMediator

itemChanged()

unselectAll()

viewModel

Service Bus

Friday, June 29, 12

Page 57: Building Rich User Experiences Without JavaScript Spaghetti

NavControlMediator

itemSelected()

Events from some other object

unselectAll()

viewModel

ReportMediator

itemChanged()

unselectAll()

viewModel

Service Bus

HistoryControl

Friday, June 29, 12

Page 58: Building Rich User Experiences Without JavaScript Spaghetti

Service Bus

TeamControl

Gets team changed message, makes AJAX

call for this team’s data, rewrites team with template

No view model

Friday, June 29, 12

Page 59: Building Rich User Experiences Without JavaScript Spaghetti

Service Bus

Friday, June 29, 12

Page 60: Building Rich User Experiences Without JavaScript Spaghetti

Questions About Patterns?

Friday, June 29, 12

Page 61: Building Rich User Experiences Without JavaScript Spaghetti

A Typical Product LifecycleRound Two

Friday, June 29, 12

Page 62: Building Rich User Experiences Without JavaScript Spaghetti

We need this feature

Friday, June 29, 12

Page 63: Building Rich User Experiences Without JavaScript Spaghetti

I got a fewquestions

Friday, June 29, 12

Page 64: Building Rich User Experiences Without JavaScript Spaghetti

?

Friday, June 29, 12

Page 65: Building Rich User Experiences Without JavaScript Spaghetti

Tweaking time...

Friday, June 29, 12

Page 66: Building Rich User Experiences Without JavaScript Spaghetti

I got anothergreat idea

Friday, June 29, 12

Page 67: Building Rich User Experiences Without JavaScript Spaghetti

Ok, Cool

Friday, June 29, 12

Page 68: Building Rich User Experiences Without JavaScript Spaghetti

And anotherthing...

Friday, June 29, 12

Page 69: Building Rich User Experiences Without JavaScript Spaghetti

Done.

Friday, June 29, 12

Page 70: Building Rich User Experiences Without JavaScript Spaghetti

Two weeks pass...

Friday, June 29, 12

Page 71: Building Rich User Experiences Without JavaScript Spaghetti

I’ve got a new feature

Friday, June 29, 12

Page 72: Building Rich User Experiences Without JavaScript Spaghetti

No worries.

Friday, June 29, 12

Page 73: Building Rich User Experiences Without JavaScript Spaghetti

Wha? Ohhhk.

Friday, June 29, 12

Page 74: Building Rich User Experiences Without JavaScript Spaghetti

A short time later...

Friday, June 29, 12

Page 75: Building Rich User Experiences Without JavaScript Spaghetti

Friday, June 29, 12

Page 76: Building Rich User Experiences Without JavaScript Spaghetti

Special thanks to

He did the frame artBlame me for

everything else

Friday, June 29, 12

Page 77: Building Rich User Experiences Without JavaScript Spaghetti

Examples

Friday, June 29, 12

Page 78: Building Rich User Experiences Without JavaScript Spaghetti

A KO Warning

It’s really easy to go overboard with KO events.

I prefer to use KO for the VM binding (observables and computeds) but rely on jQuery for events.

jQuery’s .on() binding and a good understanding of ‘this’ makes for much cleaner events.

Friday, June 29, 12

Page 79: Building Rich User Experiences Without JavaScript Spaghetti

Easy Testing

Try to have layers of your application’s JS that don’t touch any HTML elements.

Store data in models inside individual controls and test that published messages change the state of those

models correctly.

Friday, June 29, 12

Page 80: Building Rich User Experiences Without JavaScript Spaghetti

Why Not Backbone.js?

Friday, June 29, 12

Page 81: Building Rich User Experiences Without JavaScript Spaghetti

Shared Model

Friday, June 29, 12

Page 82: Building Rich User Experiences Without JavaScript Spaghetti

NavControlMediator

itemSelected()

Events from some other object

unselectAll()

viewModel

ReportMediator

itemChanged()

unselectAll()

viewModel

Service Bus

Friday, June 29, 12

Page 83: Building Rich User Experiences Without JavaScript Spaghetti

Tools Make This Easier

Underscore.jsCoffeescriptTemplates

Friday, June 29, 12

Page 84: Building Rich User Experiences Without JavaScript Spaghetti

Knockout.js - Observer pattern (pub/sub)http://knockoutjs.com/

http://learn.knockoutjs.com/

Postal.js - Service bushttps://github.com/ifandelse/postal.js

http://freshbrewedcode.com/jimcowart/2011/12/05/client-side-messaging-with-postal-js-part-1/http://www.jaredthenerd.com/2012/01/using-postaljs-for-client-side.html

Patternshttp://arguments.callee.info/2009/05/18/javascript-design-patterns--mediator/

http://msdn.microsoft.com/en-us/magazine/hh201955.aspx (Pub/Sub)

Friday, June 29, 12