Javascript spaghetti stirtrek_5_17

Post on 01-Nov-2014

538 views 0 download

Tags:

description

 

transcript

Building Rich User Experienceswithout

JavaScript Spaghetti

by Jared Faris

@jaredthenerd

jaredthenerd.com

About me

Traditional Web Development

Web assets are created last to glue together things.

Stakeholders, architects and developers define the

“real” application.

The application is built model first (from the DB up).

Traditional Web Development

The design is focused on making the CRUD pretty, not

usable

The design of the UI/UX happens in Photoshop... if it

happens at all.

Most of the application is just CRUD.

We have a widgets

table

We need a

widgets

screen!

Traditional Web Development

“Advanced” web developers write lots of unorganized

bits of jQuery.

Most user interactions result in lots of POSTS back

to the server.

JavaScripts are something someone download from

hotscripts.com.

We have a widgets

table

We need a

widgets

screen!

Make sure you

add a date picker

And a lighbox!

JavaScript: Not a “Real” Language

Patternless design.

Built as a glue to bind pieces together, not as a core

component of the application.

Not thought through like server-side code.

Not Real? Why?

A lot of development tools traditionally hid the JS behind

configurable controls.

Libraries like jQuery make it really easy to pile on lots of

little events.

JS used to be a tool for doing image rollovers.

Is That A Problem?

In a workflow-based application it falls apart.

For form-based apps that was mostly fine.

Customized, reusable controls and a modular

application design needs something more.

Questions So Far?

A Typical Product LifecycleSomewhat dramatized...

Designer Developer

We need this

feature

I got this

?

Tweaking time...

I got another

great idea

Now you tell

me

The developer bolts on some more code

And another

thing...

grrr

We don’t

‘really’need this

Uh, yeah we

do

The developer bolts on some more code

Some time passes

‘Some time’ is defined as:

Just long enough that the developer doesn’t remember

exactly how his original code works.

I’ve got a new

feature

Angry developers

can really do this.

IT managers be

warned.

Protective Beret

More messy code

The last bug

Oh wait, one more

Finally

(14 tests ought to be enough for anybody)

The next day...

Two weeks pass.

I’ve got a new

featureGahh!

No developers were harmed in the making

of this dramatic reenactment.

Poor design patterns

+ crappy code

= JavaScript spaghetti

Why does this happen?

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*

* Or at least it used to

This really all boils down to one thing.

We developers suck.

Three JavaScript Principles

Push events, not state

Write small, discrete bits of code

Decouple everything

Decouple Everything

Apply your OO best practices here too.

Remove dependencies between objects.

Start thinking about UI pieces as individual JS objects.

Small Chunks Of Code

Even if you don’t test everything, learning how to

write testable code means learning

how to write better code

Put the rest of the stuff in classes that you can test.

Separate DOM dependent stuff into a single layer.

Push Events, Not State

Inform other controls that “X happened to Y”,

not “Y is in X state”

Let controls worry about their own state.

Know about the Law of Demeter.

Writing Better JavaScript

Find the tools that make your life easier.

Use the design patterns you already know.

Leverage language features whether JS has them or not.

Language Features

Keep state inside of the objects and expose methods.

Objects have state and behavior.

JavaScript loves its objects. Create them to represent

page elements.

Language “Features”

Consider using namespaces.

JavaScript Namespacing

Language “Features”

Use inheritance or faux subclassing.

Consider using namespaces.

JavaScript Prototyping

Coffeescript Classes

Language “Features”

Pass JSON around asynchronously.

Use inheritance or faux subclassing.

Consider using namespaces.

Design Patterns

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

NavControlMediator

itemSelected()

Events from some

other object

unselectAll()

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()

NavControlMediator

itemSelected()

Events from some

other object

unselectAll()

viewModel

Tools & Frameworks

Knockout

Magic.

Setup a template with some markup binding it.

Setup a JavaScript object with some KO code.

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.

Backbone

Views help you control the visual rendering.

Routers help you organize page flow.

While KO is Model < > View magic, Backbone is structure.

Models help you keep track of state.

Backbone Use Case

What about all the other

frameworks?

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.

Way Too Much Pubbing and Subbing

Service Bus

Your controls are then only coupled to a single thing.

Controls that want to communicate speak through it.

A service bus is another layer that sits outside controls.

Postal.js

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.

NavControlMediator

itemSelected()

Events from some

other object

unselectAll()

viewModel

ReportMediator

itemChanged()

unselectAll()

viewModel

Service Bus

NavControlMediator

itemSelected()

Events from some

other object

unselectAll()

viewModel

ReportMediator

itemChanged()

unselectAll()

viewModel

Service Bus

HistoryControl

Service Bus

TeamControl

Gets team changed

message, makes AJAX

call for this team’s data,

rewrites team with template

No view model

Service Bus

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.

Underscore

Underscore

Underscore w/ Coffeescript

What Else?

I don’t have a third bullet point here

Browser Debuggers

Templates

A Typical Product LifecycleRound Two

We need this

feature

I got a few

questions

?

Tweaking time...

I got another

great idea

Ok, Cool

And another

thing...

Done.

Two weeks pass...

I’ve got a new

feature

No worries.

Wha? Ohhhk.

A short time later...

Examples

Questions?

Special thanks to

He did the frame art

Blame me for

everything else

My Stuff@jaredthenerd

jfaris@gmail.com

https://github.com/jaredfaris

http://jaredthenerd.com