Date post: | 02-Nov-2014 |
Category: |
Technology |
Upload: | jared-faris |
View: | 1,471 times |
Download: | 0 times |
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 widgetstable
We need awidgetsscreen!
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 widgetstable
We need awidgetsscreen!
Make sure youadd 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 anothergreat idea
Now you tellme
The developer bolts on some more code
And anotherthing...
grrr
We don’t ‘really’
need this
Uh, yeah wedo
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 developerscan really do this.IT managers be
warned.
Protective Beret
More messy code
The last bug
Oh wait, one more
Finally
The next day...
Two weeks pass.
I’ve got a new feature Gahh!
No developers were harmed in the makingof 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 towrite 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 representpage 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
Backbone vs Knockout?
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
Examples
Questions?
A Typical Product LifecycleRound Two
We need this feature
I got a fewquestions
?
Tweaking time...
I got anothergreat idea
Ok, Cool
And anotherthing...
Done.
Two weeks pass...
I’ve got a new feature
No worries.
Wha? Ohhhk.
A short time later...
Special thanks to
He did the frame art
Blame me foreverything else
My Stuff@jaredthenerd
[email protected]://github.com/jaredfaris
http://jaredthenerd.com
Rate Mehttp://spkr8.com/t/19171