Slide 1

Slide 1 text

ASYNCJS

Slide 2

Slide 2 text

WE’RE AT AN INTERESTING POINT IN TIME 1999 EcmaScript 3 2004 Dojo Toolkit 2006 jQuery 2009 EcmaScript 5 2009 RequireJS 2008 JavaScriptMVC 2007 SproutCore/Ember 2010 Backbone.js 2011 Spine.js JavaScript is no longer just being used to enhance the user-experience on sites, it’s being used to build complex applications. 2012

Slide 3

Slide 3 text

modularity maintainability performance internationalization scale Larger-applications come with greater concerns. size structure WITH MANY GREAT CHALLENGES TO FACE

Slide 4

Slide 4 text

A well planned architecture helps building applications that can scale and help tackle these problems.

Slide 5

Slide 5 text

Here are some pointers before we get started New to this? • Remember that libraries like jQuery are only a small part of a much larger puzzle • Unlike Dojo, jQuery doesn’t provide recommendations about application structure • Luckily, there are lots of solutions to this for building small, medium and large apps.

Slide 6

Slide 6 text

How to structure small to medium sized applications Organising your code

Slide 7

Slide 7 text

Architecture patterns help de ne the structure for an application. How many of them do you know?

Slide 8

Slide 8 text

The Model-View-Controller pattern Architecture MVC Provides a clean separation of concerns where data (Models), presentation (Views) and user- input (Controllers) are handled separately. Uses the Observer pattern to watch for changes to data, state. (more on this soon)

Slide 9

Slide 9 text

The Model-View-Presenter pattern Architecture MVP Like MVC, but with a heavier focus on UI. The P (presenter) plays the role of the Controller with the View handling user-input.

Slide 10

Slide 10 text

The Model-View ViewModel pattern Architecture MVVM Similarly like MVC, but the ViewModel provides data bindings between the Model and View. Converts Model data and passes it on to the View for usage.

Slide 11

Slide 11 text

Variations on these patterns Architecture MV* Patterns which borrow aspects from a number of others and don’t fall under a speci c name. Developers commonly try tting solutions that fall under MV* into one of the others but shouldn’t.

Slide 12

Slide 12 text

The pattern most commonly used on the front-end these days is ‘MVC’. *It’s of course not the *only* option, just the most frequently used.

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

None are really using MVC - it’s MV*. Smalltalk-80 had the rst version of MVC and it was very different, but it’s evolved through time. Different languages have interpreted it differently. Did you know?

Slide 15

Slide 15 text

Why care? Understanding patterns allows us to use MV* frameworks more effectively.

Slide 16

Slide 16 text

Separates applications into three main concerns: The MVC Pattern Models Views Controllers

Slide 17

Slide 17 text

Manage the behaviour of the application data MVC: Models • Represent knowledge and data • Respond to requests about state • Isolated from views and controllers • Sometimes grouped (e.g collections)

Slide 18

Slide 18 text

Render models into a form suitable for user interaction MVC: Views • In most cases can be considered the UI • Typically render to a speci c user interface element • Many frameworks rely on templating for this • Multiple views can exist for single models

Slide 19

Slide 19 text

Receive input and instruct models and views to respond accordingly MVC: Controllers • Sits between models and views • (May) perform business logic and data manipulation • It’s role in client-side MVC heavily varies • In some implementations views observe models

Slide 20

Slide 20 text

Converting spaghetti code to use MVC isn’t all that hard.. How Does This Work? Models Views Controllers Spaghetti code What unique data is represented in my app? e.g a picture, a person What does the user need to be able to see and do? What (repeatable) output can I shift to JS templating? (varies) Typically handle user interaction

Slide 21

Slide 21 text

Converting spaghetti code to use MVC isn’t all that hard.. How Does This Work? Models Views Controllers Spaghetti code What unique data is represented in my app? e.g a picture, a person What does the user need to be able to see and do? What (repeatable) output can I shift to JS templating? (varies) Typically handle user interaction

Slide 22

Slide 22 text

Converting spaghetti code to use MVC isn’t all that hard.. How Does This Work? Models Views Controllers Spaghetti code What unique data is represented in my app? e.g a picture, a person What does the user need to be able to see and do? What (repeatable) output can I shift to JS templating? (varies) Typically handle user interaction

Slide 23

Slide 23 text

All JavaScript ‘MVC’ frameworks interpret MVC differently. Not a bad thing, but it’s very useful to be aware of this fact.

Slide 24

Slide 24 text

How does Backbone.js view the MVC pattern? Backbone’s MVC Models Views Collections Routers Domain-level data User-interface Closer to Controller Like the ‘P’ in MVP Groups of models Map URLs to functions

Slide 25

Slide 25 text

Pick the framework that makes the most sense for you I like Backbone because it has: Why Backbone.js? • Flexible conventions for structuring applications • Event-driven communication between views and models (sense and respond) • Supports data bindings through manual events • Successfully used by large companies on non- trivial applications (SoundCloud, Foursquare)

Slide 26

Slide 26 text

Frameworks and libraries that provide MV* implementations MV* Implementations • Backbone.js • Spine.js • YUILibrary • JavaScriptMVC • AngularJS • Ember.js • Sammy.js • Batman.js • Broke.js • KnockoutJS (MVVM)

Slide 27

Slide 27 text

A quick overview of what’s available Very-quick guide • Backbone.js - light, mature, popular. • JavaScriptMVC - mature, integrated dev tools • Spine.js - < core than Backbone, better for CS devs • Ember.js - SproutCore 2.0 base, bindings • Sammy.js - routes/controllers but no MV. Better for bootstrapping just the parts needed

Slide 28

Slide 28 text

To help make picking a framework easier, I created TodoMVC.

Slide 29

Slide 29 text

http://addyosmani.github.com/todomvc Same app, different frameworks.

Slide 30

Slide 30 text

With the same functionality, it’s easier to compare implementations. Easy to compare implementations

Slide 31

Slide 31 text

Vanilla JS vs. Backbone.js (code walkthrough)

Slide 32

Slide 32 text

Writing code that’s expressive, encapsulated & structured Modular JavaScript

Slide 33

Slide 33 text

The typical module pattern is where immediately invoked function expressions (IIFEs) use execution context to create ‘privacy’. Here, objects are returned instead of functions. Module Pattern var basketModule = (function() { var basket = []; //private return { //exposed to public addItem: function(values) { basket.push(values); }, getItemCount: function() { return basket.length; }, getTotal: function(){ var q = this.getItemCount(),p=0; while(q--){ p+= basket[q].price; } return p; } } }()); • In the pattern, variables/ functions declared are only available inside the module. • Those de ned within the returning object are available to everyone • This allows us to simulate privacy

Slide 34

Slide 34 text

A module format proposed for EcmaScript Harmony with goals such as static scoping, simplicity and usability. This isn’t nal. ES Harmony: Improved Modules // Basic module module SafeWidget { import alert from Widget; var _private ="someValue"; // exports export var document = { write: function(txt) { alert('Out of luck, buck'); }, ... }; }

Slide 35

Slide 35 text

Load modules from remote sources or dynamically (something you would do to only load additional scripts when they are needed and not on page-load) ES Harmony: Loading Modules // Modules loaded from remote sources module cakeFactory from'http://addyosmani.com/factory/cakes.js'; cakeFactory.oven.makeMuffin('large'); // Module Loader API for dynamic loading Loader.load('http://addyosmani.com/factory/cakes.js', function(cakeFactory){ cakeFactory.oven.makeCupcake('chocolate'); });

Slide 36

Slide 36 text

Modules for the server-side which provide functionality similar to what you may nd in CommonJS, an alternative to AMD better suited to the server ES Harmony: CommonJS-like Modules // io/File.js export function open(path) { ... }; // compiler/LexicalHandler.js module file from 'io/File'; import { open } from file; export function scan(in) { var h = open(in) ... } // We can then reuse our modules module lexer from 'compiler/LexicalHandler'; module stdlib from '@std';

Slide 37

Slide 37 text

Take the concept of reusable JavaScript modules further with the Asynchronous Module De nition. Flexible Modules Today: AMD Mechanism for de ning asynchronously loadable modules & dependencies Non-blocking, parallel loading and well de ned. Stepping-stone to the module system proposed for ES Harmony

Slide 38

Slide 38 text

de ne allows the de nition of modules with a signature of de ne(id /*optional*/, [dependencies], factory /*module instantiation fn*/); AMD: de ne() /* wrapper */ define( /*module id*/ 'myModule', /*dependencies*/ ['foo','bar','foobar'], /*definition for the module export*/ function (foo, bar, foobar) { /*module object*/ var module = {}; /*module methods go here*/ module.hello = foo.getSomething(); module.world = bar.doSomething(); /*return the defined module object*/ return module; } );

Slide 39

Slide 39 text

require is used to load code for top-level JS les or inside modules for dynamically fetching dependencies AMD: require() define(function ( require ) { var isReady = false, foobar; // note the inline require within our module definition require(['foo', 'bar'], function (foo, bar) { isReady = true; foobar = foo() + bar(); }); // we can still return a module return { isReady: isReady, foobar: foobar }; });

Slide 40

Slide 40 text

AMD modules can be used with RequireJS and curl.js amongst other script loaders. They’re compatible with Dojo, MooTools and even jQuery.

Slide 41

Slide 41 text

Why do we need solutions like it? RequireJS Clean import/require for JavaScript Easily load nested dependencies Optimizer for packaging scripts to avoid excessive HTTP calls

Slide 42

Slide 42 text

A very simple AMD module using jQuery and the color plugin AMD + jQuery define(["jquery", "jquery.color", "jquery.bounce"], function($) { //the jquery.color and jquery.bounce plugins have been loaded // not exposed to other modules $(function() { $('#container') .animate({'backgroundColor':'#ccc'}, 500) .bounce(); }); // exposed to other modules return function () { // your module's functionality }; });

Slide 43

Slide 43 text

Want to wait until dependencies have resolved before continuing? Easy. Deferred dependencies // This could be compatible with jQuery's Deferred implementation, // futures.js (slightly different syntax) or any one of a number // of other implementations define(['lib/Deferred'], function( Deferred ){ var defer = new Deferred(); require(['lib/templates/?index.html','lib/data/?stats'], function( template, data ){ defer.resolve({ template: template, data:data }); } ); return defer.promise(); });

Slide 44

Slide 44 text

Templates can be loaded in using the RequireJS text plugin External templates define([ 'jquery', 'underscore', 'backbone', 'text!templates/mytemplate.html' ], function($, _, Backbone, myTemplate){ var TodoView = Backbone.View.extend({ //... is a list tag. tagName: "li", // Cache the template function for a single item. template: _.template(myTemplate),

Slide 45

Slide 45 text

Clearing up confusions about AMD and RequireJS Misconceptions • define wrappers aren’t that much more code • Most AMD users are (or should) be using a build process to wrap everything up • r.js allows you to optimize your AMD modules and does a lot more out of the box • Alternative approaches still years away

Slide 46

Slide 46 text

Backbone.js + RequireJS + AMD + jQuery walkthrough https://github.com/addyosmani/backbone-aura *or look at:

Slide 47

Slide 47 text

Strategies for decoupling and future-proo ng the structure of your application. Let’s build empires. Large-Scale Application Architecture Thanks to Nicholas Zakas, Rebecca Murphey, John Hann, Paul Irish, Peter Michaux and Justin Meyer for their previous work in this area.

Slide 48

Slide 48 text

Large-scale JavaScript apps are non-trivial applications requiring signi cant developer effort to maintain, where most heavy lifting of data manipulation and display falls to the browser. What is a ‘large’ JS app?

Slide 49

Slide 49 text

GWT -> JavaScript, large number of components, heavy reliance on client-side implementation to perform optimally Example: GMail

Slide 50

Slide 50 text

The homepage is extremely modularized where distinct components don’t need to be aware of each other Example: Yahoo!

Slide 51

Slide 51 text

might contain a mixture of the following: Your Current Architecture MVC (Models/Views/Controllers) An Application Core Modules Custom Widgets JavaScript Libraries & Toolkits

Slide 52

Slide 52 text

If working on a signi cantly large JavaScript app, remember to dedicate suf cient time to planning the underlying architecture that makes the most sense. It’s often more complex than we initially think.

Slide 53

Slide 53 text

You may be using some great architectural components, but implemented non- optimally they can come with a few problems: Possible Problems How much of this is instantly re-usable? Can single modules exist on their own independently? Can single modules be tested independently?

Slide 54

Slide 54 text

Some further concerns: Possible Problems How much do modules depend on others in the system? Is your application tightly coupled? If speci c parts of your app fail, can it still function?

Slide 55

Slide 55 text

Think long term - what future concerns haven’t been factored in yet?

Slide 56

Slide 56 text

“The secret to building large apps is never build large apps. Break your applications into small pieces. Then, assemble those testable, bite-sized pieces into your big application” - Justin Meyer

Slide 57

Slide 57 text

“The more tied components are to each other, the less reusable they will be, and the more dif cult it becomes to make changes to one without accidentally affecting another” - Rebecca Murphey

Slide 58

Slide 58 text

If you haven’t used them before yourself a library you use may have! LET’S TAKE A QUICK BREAK TO REVIEW TWO CLASSICAL PATTERNS FACADE MEDIATOR

Slide 59

Slide 59 text

Convenient, high-level interfaces to larger bodies of code that hide underlying complexity Facade Pattern “When you put up a facade, you're usually creating an outward appearance which conceals a different reality. Think of it as simplifying the API presented to other developers” - Essential JavaScript Design Patterns

Slide 60

Slide 60 text

var module = (function() { var _private = { i:5, get : function() { console.log('current value:' + this.i); }, set : function( val ) { this.i = val; }, run : function() { console.log('running'); }, jump: function(){ console.log('jumping'); } }; return { facade : function( args ) { _private.set(args.val); _private.get(); if ( args.run ) { _private.run(); } } } }()); module.facade({run: true, val:10}); //outputs current value: 10, running A higher-level facade is provided to our underlying module, without directly exposing methods. Facade Implementation We’re really just interested in this part.

Slide 61

Slide 61 text

A higher-level facade is provided to our underlying module, without directly exposing methods. Facade Implementation return { facade : function( args ) { // set values of private properties _private.set(args.val); // test setter _private.get(); // optional: provide a simple interface // to internal methods through the // facade signature if ( args.run ) { _private.run(); } } } Limited public API of functionality. Differs greatly from the reality of the implementation.

Slide 62

Slide 62 text

A structural pattern found in many JavaScript libraries and frameworks (eg. jQuery). A Facade Simpli es usage through a limited, more readable API Hides the inner- workings of a library. Allows implementation to be less important. This lets you be more creative behind the scenes.

Slide 63

Slide 63 text

How does it differ from the module pattern? Facade vs. Module • Differs from the module pattern as the exposed API can greatly differ from the public/private methods de ned • Has many uses including application security as we’ll see a little later in the talk

Slide 64

Slide 64 text

Encapsulates how disparate modules interact with each other by acting as an intermediary Mediator Pattern “Mediators are used when the communication between modules may be complex, but is still well de ned” - Essential JavaScript Design Patterns

Slide 65

Slide 65 text

I always nd this mediator analogy helps when discussing this pattern: Air Traf c Control The tower handles what planes can take off and land All communication done from planes to tower, not plane to plane Centralised controller is key to this success. Similar to mediator.

Slide 66

Slide 66 text

Promotes loose coupling. Helps solve module inter-dependency issues. A Mediator Allow modules to broadcast or listen for noti cations without worrying about the system. Noti cations can be handled by any number of modules at once. Typically easier to add or remove features to loosely coupled systems like this.

Slide 67

Slide 67 text

One possible implementation, exposing publish and subscribe capabilities. Mediator Implementation var mediator = (function(){ var subscribe = function(channel, fn){ if (!mediator.channels[channel])mediator.channels[channel] = []; mediator.channels[channel].push({ context: this, callback:fn }); return this; }, publish = function(channel){ if (!mediator.channels[channel]) return false; var args = Array.prototype.slice.call(arguments, 1); for (var i = 0, l = mediator.channels[channel].length; i

Slide 68

Slide 68 text

Usage of the implementation from the last slide. Example //Pub/sub via a centralized mediator mediator.name = "tim"; mediator.subscribe('nameChange', function(arg){ console.log(this.name); this.name = arg; console.log(this.name); }); mediator.publish('nameChange', 'david'); //tim, david

Slide 69

Slide 69 text

Fixing our architecture with what we’ve learned to date. Solution: Combine Patterns “The only difference between a problem and a solution is that people understand the solution.’ - Charles F. Kettering

Slide 70

Slide 70 text

We’re going to build something special. Let’s Combine Our Patterns Module Pattern Facade Pattern Mediator Pattern + + = WIN

Slide 71

Slide 71 text

What do we want? Brainstorm. Loosely coupled architecture Functionality broken down into smaller independent modules Framework or library agnostic. Flexibility to change in future. (optional)

Slide 72

Slide 72 text

How might we achieve this? Some More Ideas. Single modules speak to the app when something interesting happens An intermediate layer interprets requests. Modules don’t access the core or libraries directly. Prevent apps from falling over due to errors with speci c modules.

Slide 73

Slide 73 text

The Facade An abstraction of the core, it listens out for interesting events and says ‘Great. What happened? Give me the details’. It also acts as a permissions manager. Modules only communicate through this and are only able to do what they’ve been permitted to.

Slide 74

Slide 74 text

How else can it help? The Facade • Components communicate via the facade so it needs to be dependable • It acts as a security guard, determining which parts of the application a module can access • Components only call their own methods or methods from a sandbox, but nothing they don’t have permission to

Slide 75

Slide 75 text

The Application Core (Mediator) Manages the module lifecycle. It reacts to events passed from the facade and starts, stops or restarts modules as necessary. Modules here automatically execute when loaded.

Slide 76

Slide 76 text

The Mediator Pattern The Application Core • It’s not the core’s job to decide whether this should be when the DOM is ready. • The core should enable adding or removing modules without breaking anything. • It should ideally also handle detecting and managing errors in the system.

Slide 77

Slide 77 text

This is how modules might normally communicate with the mediator. Standalone Mediator

Slide 78

Slide 78 text

This is where the Facade ts in. The intermediate security layer that pipes noti cations back to the mediator for processing. Mediator + Facade Permission granted Permission granted

Slide 79

Slide 79 text

Modules Unique blocks of functionality for your application. They inform the application when something interesting happens. Don’t talk to each other directly, only concerned with publishing events of interest.

Slide 80

Slide 80 text

Modules contain speci c pieces of functionality for your application. They publish noti cations informing the application whenever something interesting happens Modules

Slide 81

Slide 81 text

If a single module fails, the facade and mediator should stop and restart it. Modules

Slide 82

Slide 82 text

Demo: Backbone.js + RequireJS + AMD modules + facade + mediator pattern https://github.com/addyosmani/backbone-aura

Slide 83

Slide 83 text

Demo: Aura : use this architecture to easily swap jQuery for Dojo or visa versa in one line of code.

Slide 84

Slide 84 text

Let’s review what we looked at today. What We Learned ‘Anyone who stops learning is old, whether at twenty or eighty. Anyone who keeps learning stays young. The greatest thing in life is to keep your mind young’ - Henry Ford

Slide 85

Slide 85 text

Architecture. Modularity. Scalability.

Slide 86

Slide 86 text

We looked at design patterns to create scalable ‘future-proof’ application architectures. For large apps consider an: Summary Application core Mediator Module manager Swappable Facade Core abstraction Permission manager Modules Highly decoupled Unique blocks (Optionally) Framework agnostic

Slide 87

Slide 87 text

This can be very useful as: Summary • Modules are no longer dependent on anyone • They can be managed so that the application doesn’t (or shouldn’t) fall over. • You can theoretically pick up any module, drop it in a page and start using it in another project

Slide 88

Slide 88 text

I’ve written about some of these topics in more depth: Further Reading • Understanding MVC & MVP For JS Developers http:// bit.ly/wJRR59 • Patterns For Large-scale JavaScript Application Architecture http://addyosmani.com/largescalejavascript/ • Writing Modular JavaScript with AMD, CommonJS & ES Harmony http://addyosmani.com/writing-modular-js

Slide 89

Slide 89 text

I’ve written about some of these topics in more depth: Further Reading • Backbone Fundamentals (book): http:// backbonefundamentals.com • Essential JavaScript Design Patterns (e-book) http:// bit.ly/bMyoQ9 • Building Large-Scale jQuery Applications http:// addyosmani.com/blog/large-scale-jquery/

Slide 90

Slide 90 text

For more on this architecture and other topics, check out: That’s it. Blog Twitter GitHub http://addyosmani.com @addyosmani or @addy_osmani http://github.com/addyosmani