Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.
Thursday, 6 October 2011
Introduction                                 What are we looking at today?                                                ...
About Me                                       Some quick info.                    • JavaScript & UI Developer @AOL       ...
We used to make these:Thursday, 6 October 2011
Which now make awesome pizza-cuttersThursday, 6 October 2011
Let’s get started.Thursday, 6 October 2011
We’re Individuals                  We all like doing things a little bit differently.                “You have your way. I...
Thursday, 6 October 2011
We all do things differently                           Each of us have preferences for how we approach the below:         ...
Great but can lead to..                           serious problems when working on code to be used by others.             ...
A lot like how most Stormtroopers know that there’s a time,                     a place and a way to wear your uniform..an...
Thursday, 6 October 2011
Design Patterns                  Reusable solutions that can be applied to commonly                  occurring problems in...
They’re proven                  Patterns are generally proven to have successfully solved problems in the past.           ...
They’re reusable                           Patterns can be picked up, improved and adapted without great effort.          ...
Thursday, 6 October 2011
They’re expressive                           Patterns provide us a means to describing approaches or structures.          ...
JavaScript Design                Patterns                  Writing code that’s expressive, encapsulated                  &...
Module Pattern                  Interchangeable single-parts of a larger system that can be                  easily re-use...
Stepping stone: IIFE                           Immediately invoked function expressions (or self-executing anonymous funct...
But...Thursday, 6 October 2011
Thursday, 6 October 2011
Privacy In Modules                            There isn’t a true sense of ‘privacy’ inside JavaScript.                    ...
Simulate privacy                    The typical module pattern is where immediately invoked function expressions (IIFEs) u...
Module Pattern: Dojo                   Dojo attempts to provide class-like functionality through dojo.declare, which can b...
Module Pattern: jQuery                In the following example, a library function is de ned which declares a new library ...
Module Pattern: YUI                           A YUI module pattern implementation that follows the same general concept.  ...
Better: AMD                           Take the concept of reusable JavaScript modules further with the                    ...
AMD: de ne()                            de ne allows the de nition of modules with a signature of                    de ne...
AMD: require()                           require is used to load code for top-level JS les or inside modules for          ...
Alternative: CommonJS                           Another easy to use module system with wide adoption server-side          ...
CommonJS Modules                  They basically contain two parts: an exports object that contains the objects a         ...
Better alternative: Universal Module De nition                  De ning modules that can work anywhere (CommonJS environme...
ES Harmony Modules                           A module format proposed for EcmaScript Harmony with goals such as static sco...
Facade Pattern                  Convenient, high-level interfaces to larger bodies of code                  that hide unde...
Thursday, 6 October 2011
Example                           A higher-level facade is provided to our underlying module, without directly exposing me...
A Facade                   A structural pattern found in many JavaScript libraries and frameworks (eg. jQuery).           ...
Mediator Pattern                  Encapsulates how disparate modules interact with each                  other by acting a...
Air Traf c Control                           I always nd this mediator analogy helps when discussing this pattern:        ...
A Mediator                           Promotes loose coupling. Helps solve module inter-dependency issues.          Allow m...
Mediator Implementation                           One possible implementation, exposing publish and subscribe capabilities...
Example                                     Usage of the implementation from the last slide.      //Pub/sub on a centraliz...
Scalable Application                Architecture                  Strategies for decoupling and future-proo ng the structu...
Thursday, 6 October 2011
De ne a ‘large’ JS app.                   Large-scale JavaScript apps are non-trivial                applications requirin...
Some Examples                               Google’s GMailThursday, 6 October 2011
Some Examples                              The Yahoo! HomepageThursday, 6 October 2011
Some Examples                               AOL Mail / PhoenixThursday, 6 October 2011
Current Architecture                  If working on a signi cantly large JavaScript app,                  remember to dedi...
Thursday, 6 October 2011
Your Current Architecture                             might contain a mixture of the following:                           ...
Possible Problems                    The last slide contains some great architectural components, but used non-           ...
Possible Problems                                     Some further concerns:                How much do              Is yo...
Think Long-Term                           What future concerns haven’t been factored in to this architecture?             ...
Ask Yourself                                    This is important.                   If you reviewed your architecture rig...
A Solution                  Fixing our architecture with JavaScript design patterns.                “The only difference b...
Thursday, 6 October 2011
Let’s Combine Our Patterns                                  We’re going to build something special.                       ...
Let’s Think.                                    What do we want?                                  Functionality broken    ...
Some More Ideas.                               How might we achieve this?                               An intermediate la...
The Facade              An abstraction of the core, it listens out for interesting              events and says ‘Great. Wh...
The Application Core              Manages the module lifecycle. It reacts to events passed              from the facade an...
Modules              Unique blocks of functionality for your application. They              inform the application when so...
Aura: A Preview                  Enough talk! Let’s take a look at some real code.                Aura is a framework I’m ...
Aura: Core                                         The Mediator / Application Core                           •   Swappable...
Aura: Core                                             How does this work?                           •   Accessing this wr...
Aura: Core                           A sample of the method signatures and namespaces supported       // some core methods...
Aura: Core.dom > Chaining, CSS                 Chaining and CSS Style Manipulation are both supported. Behind the scenes, ...
Aura: Core.dom > Attribs, Anim                  Attribute manipulation and animation are also abstracted using an API simi...
Aura: Core.dom > Create, Ajax                           Similarly, element creation and ajax are also supported in the abs...
Aura: Aura.f (Facade)                    A very lightweight implementation of the facade pattern that provides modules    ...
Aura: Modules > add-todo.js                                    Module wireframe.    aura.core.define("#todo-list", functio...
Aura: Modules > add-todo.js                                   Module for adding new Todo items to a container on a page   ...
Aura: Modules > add-todo.js                 Note how modules are only concerned with publishing and subscripting to noti c...
Aura: Modules > add-todo.js                 The facade allows access to everything from DOM query methods to dynamic objec...
Aura: Modules > add-todo.js                               Module for adding new Todo items to a container on a page  init ...
Aura: Modules > counter.js                             And here’s a basic module that consumes the noti cations from the l...
What We Learned                  Let’s review what we looked at today.                ‘Anyone who stops learning is old, w...
Summary                   Today we learned how to use three design patterns to create scalable ‘future-                   ...
That’s it.                                  For more on this architecture and other topics, check out:                    ...
Thursday, 6 October 2011
Prochain SlideShare
Chargement dans…5
×

Future-proofing Your JavaScript Apps (Compact edition)

40 078 vues

Publié le

Future proofing your JavaScript applications with effective architectural design patterns.

Publié dans : Technologie, Design

Future-proofing Your JavaScript Apps (Compact edition)

  1. Thursday, 6 October 2011
  2. Introduction What are we looking at today? Scalable Application Design Patterns Patterns in JavaScript ArchitectureThursday, 6 October 2011
  3. About Me Some quick info. • JavaScript & UI Developer @AOL • Member of the jQuery core [Bugs/Docs/ Learning] teams • Blogger [AddyOsmani.com/ScriptJunkie] • Author ‘Essential JavaScript Design Patterns’Thursday, 6 October 2011
  4. We used to make these:Thursday, 6 October 2011
  5. Which now make awesome pizza-cuttersThursday, 6 October 2011
  6. Let’s get started.Thursday, 6 October 2011
  7. We’re Individuals We all like doing things a little bit differently. “You have your way. I have my way. As for the right way, the correct way, and the only way, it does not exist.” - Friedrich NietzscheThursday, 6 October 2011
  8. Thursday, 6 October 2011
  9. We all do things differently Each of us have preferences for how we approach the below: Solving problems Structuring solutions Solving scalabilityThursday, 6 October 2011
  10. Great but can lead to.. serious problems when working on code to be used by others. Inconsistent solutions Inconsistent architecture Dif cult refactoringThursday, 6 October 2011
  11. A lot like how most Stormtroopers know that there’s a time, a place and a way to wear your uniform..and others completely ignore this.Thursday, 6 October 2011
  12. Thursday, 6 October 2011
  13. Design Patterns Reusable solutions that can be applied to commonly occurring problems in software design and architecture. “We search for some kind of harmony between two intangibles: a form we have not yet designed and a context we cannot properly describe’ - Christopher Alexander, the father of design patterns.Thursday, 6 October 2011
  14. They’re proven Patterns are generally proven to have successfully solved problems in the past. Reliable Re ect Represent Solid approaches experience insightsThursday, 6 October 2011
  15. They’re reusable Patterns can be picked up, improved and adapted without great effort. Out-of-the-box Incredibly exible Easily adapted solutionsThursday, 6 October 2011
  16. Thursday, 6 October 2011
  17. They’re expressive Patterns provide us a means to describing approaches or structures. Common vocabulary Problem agnostic Valuable as they can for expressing cut down on problems solutions elegantlyThursday, 6 October 2011
  18. JavaScript Design Patterns Writing code that’s expressive, encapsulated & structuredThursday, 6 October 2011
  19. Module Pattern Interchangeable single-parts of a larger system that can be easily re-used. “Anything can be de ned as a reusable module” - Nicholas Zakas, author ‘Professional JavaScript For Web Developers’Thursday, 6 October 2011
  20. Stepping stone: IIFE Immediately invoked function expressions (or self-executing anonymous functions) (function() {    // code to be immediately invoked    }()); // Crockford recommend this way (function() {    // code to be immediately invoked    })(); // This is just as valid (function( window, document, undefined ){     //code to be immediately invoked })( this, this.document); (function( global, undefined ){     //code to be immediately invoked })( this );Thursday, 6 October 2011
  21. But...Thursday, 6 October 2011
  22. Thursday, 6 October 2011
  23. Privacy In Modules There isn’t a true sense of ‘privacy’ inside JavaScript. Variables & Methods Variables & Methods No Access Modi ers can’t be ‘public’ can’t be ‘private’Thursday, 6 October 2011
  24. Simulate privacy The typical module pattern is where immediately invoked function expressions (IIFEs) use execution context to create ‘privacy’. Here, objects are returned instead of functions. var basketModule = (function() {     var basket = []; //private • In the pattern, variables     return { //exposed to public declared are only         addItem: function(values) { available inside the             basket.push(values); module.         },         getItemCount: function() {             return basket.length; • Variables de ned within         }, the returning object are         getTotal: function(){ available to everyone            var q = this.getItemCount(),p=0;             while(q--){                 p+= basket[q].price; • This allows us to simulate privacy             }             return p;         }     } }());Thursday, 6 October 2011
  25. Module Pattern: Dojo Dojo attempts to provide class-like functionality through dojo.declare, which can be used for amongst other things, creating implementations of the module pattern. Powerful when used with dojo.provide. //traditional way var store = window.store || {}; store.basket = store.basket || {};   //using dojo.setObject (with basket as a module of the store namespace) dojo.setObject("store.basket.object", (function() {     var basket = [];     function privateMethod() {         console.log(basket);     }     return {         publicMethod: function(){                 privateMethod();         }     }; }()));Thursday, 6 October 2011
  26. Module Pattern: jQuery In the following example, a library function is de ned which declares a new library and automatically binds up the init function to document.ready when new libraries (ie. modules) are created. function library(module) {   $(function() {     if (module.init) {       module.init();     }   });   return module; }   var myLibrary = library(function() {    return {      init: function() {        /*implementation*/      }    }; }());Thursday, 6 October 2011
  27. Module Pattern: YUI A YUI module pattern implementation that follows the same general concept. YAHOO.store.basket = function () {       //"private" variables:     var myPrivateVar = "I can be accessed only within YAHOO.store.basket .";       //"private" method:     var myPrivateMethod = function () {             YAHOO.log("I can be accessed only from within YAHOO.store.basket");         }       return {         myPublicProperty: "Im a public property.",         myPublicMethod: function () {             YAHOO.log("Im a public method.");               //Within basket, I can access "private" vars and methods:             YAHOO.log(myPrivateVar);             YAHOO.log(myPrivateMethod());               //The native scope of myPublicMethod is store so we can             //access public members using "this":             YAHOO.log(this.myPublicProperty);         }     };   }();Thursday, 6 October 2011
  28. Better: AMD Take the concept of reusable JavaScript modules further with the Asynchronous Module De nition. Mechanism for de ning Stepping-stone to the Non-blocking, parallel asynchronously loadable module system proposed loading and well de ned. modules & dependencies for ES HarmonyThursday, 6 October 2011
  29. AMD: de ne() de ne allows the de nition of modules with a signature of de ne(id /*optional*/, [dependencies], factory /*module instantiation fn*/); /* 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;     } );     Thursday, 6 October 2011
  30. AMD: require() require is used to load code for top-level JS les or inside modules for dynamically fetching dependencies /* top-level: the module exports (one, two) are passed as  function args to the callback.*/ require([one, two], function (one, two) { }); /* inside: complete example */ define(three, [one, two], function (one, two) {     /*require(string) can be used inside the function     to get the module export of a module that has     already been fetched and evaluated.*/     var temp = require(one);     /*This next line would fail*/     var bad = require(four);     /* Return a value to define the module export */     return function () {}; });Thursday, 6 October 2011
  31. Alternative: CommonJS Another easy to use module system with wide adoption server-side CommonJS Format widely accepted Competing standard. Tries Working group on a number of server-side to solve a few things AMD designing, prototyping, platforms (Node) doesn’t. standardizing JS APIsThursday, 6 October 2011
  32. CommonJS Modules They basically contain two parts: an exports object that contains the objects a module wishes to expose and a require function that modules can use to import the exports of other modules /* here we achieve compatibility with AMD and CommonJS using some boilerplate around the CommonJS module format*/ (function(define){     define(function(require,exports){          /*module contents*/          var dep1 = require("foo");          var dep2 = require("bar");          exports.hello = function(){...};          exports.world = function(){...};     }); })(typeof define=="function"? define:function(factory){factory (require,exports)});Thursday, 6 October 2011
  33. Better alternative: Universal Module De nition De ning modules that can work anywhere (CommonJS environments such as clients, servers; with script loaders etc). Thx to @KitCambridge for this version. (function (root, Library) {   // The square bracket notation is used to avoid property munging by the Closure Compiler.   if (typeof define == "function" && typeof define["amd"] =="object" && define["amd"]) {     // Export for asynchronous module loaders (e.g., RequireJS, `curl.js`).     define(["exports"], Library);   } else {     // Export for CommonJS environments, web browsers, and JavaScript engines.     Library = Library(typeof exports == "object" && exports|| (root["Library"] = {       "noConflict": (function (original) {         function noConflict() {           root["Library"] = original;           // `noConflict` cant be invoked more than once.           delete Library.noConflict;           return Library;         }         return noConflict;       })(root["Library"])     }));   } })(this, function (exports) {   // module code here   return exports; });Thursday, 6 October 2011
  34. ES Harmony Modules A module format proposed for EcmaScript Harmony with goals such as static scoping, simplicity and usability. // Basic module module SafeWidget {     import alert from Widget;     var _private ="someValue";     // exports     export var document = {         write: function(txt) {             alert(Out of luck, buck);         },         ...     }; } // Remote module module JSONTest from http://json.org/modules/json2.js;Thursday, 6 October 2011
  35. Facade Pattern Convenient, high-level interfaces to larger bodies of code that hide underlying complexity “When you put up a facade, youre usually creating an outward appearance which conceals a different reality. Think of it as simplifying the API presented to other developers” - Essential JavaScript Design PatternsThursday, 6 October 2011
  36. Thursday, 6 October 2011
  37. Example A higher-level facade is provided to our underlying module, without directly exposing methods. 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); Limited public view of functionality.             _private.get();             if ( args.run ) { Differs greatly from the reality of the                 _private.run(); implementation.             }         }     } }()); module.facade({run: true, val:10}); //outputs current value: 10, runningThursday, 6 October 2011
  38. A Facade A structural pattern found in many JavaScript libraries and frameworks (eg. jQuery). Simpli es usage by Hides the inner- This lets you be more encouraging use of workings of a library. creative behind the a limited interface for Allows implementation scenes. interaction to be less important.Thursday, 6 October 2011
  39. Mediator Pattern Encapsulates how disparate modules interact with each other by acting as an intermediary “Mediators are used when the communication between modules may be complex, but is still well de ned” - Essential JavaScript Design PatternsThursday, 6 October 2011
  40. Air Traf c Control I always nd this mediator analogy helps when discussing this pattern: The tower handles All communication done Centralised controller what planes can take from planes to tower, is key to this success. off and land not plane to plane Similar to mediator.Thursday, 6 October 2011
  41. A Mediator Promotes loose coupling. Helps solve module inter-dependency issues. Allow modules to Noti cations can be Typically easier to add or broadcast or listen for handled by any number of remove features to loosely noti cations without modules at once. coupled systems like this. worrying about the system.Thursday, 6 October 2011
  42. Mediator Implementation One possible implementation, exposing publish and subscribe capabilities. 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 <l; i++) {             var subscription = mediator.channels[channel][i];             subscription.callback.apply(subscription.context,args);         }         return this;     };       return {         channels: {},         publish: publish,         subscribe: subscribe,         installTo: function(obj){             obj.subscribe = subscribe;             obj.publish = publish;         }     }; }());Thursday, 6 October 2011
  43. Example Usage of the implementation from the last slide. //Pub/sub on 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     //Pub/sub via third party mediator   var obj = { name: sam }; mediator.installTo(obj); obj.subscribe(nameChange, function(arg){         console.log(this.name);         this.name = arg;         console.log(this.name); });   obj.publish(nameChange, john); //sam, johnThursday, 6 October 2011
  44. Scalable Application Architecture Strategies for decoupling and future-proo ng the structure of your application. Thanks to Nicholas Zakas, Rebecca Murphey, John Hann, Paul Irish, Peter Michaux and Justin Meyer for their previous work in this area.Thursday, 6 October 2011
  45. Thursday, 6 October 2011
  46. De ne a ‘large’ JS app. 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.Thursday, 6 October 2011
  47. Some Examples Google’s GMailThursday, 6 October 2011
  48. Some Examples The Yahoo! HomepageThursday, 6 October 2011
  49. Some Examples AOL Mail / PhoenixThursday, 6 October 2011
  50. Current Architecture 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.Thursday, 6 October 2011
  51. Thursday, 6 October 2011
  52. Your Current Architecture might contain a mixture of the following: Custom Widgets Modules An Application Core MVC (Models/Views/Controllers) JavaScript Libraries & ToolkitsThursday, 6 October 2011
  53. Possible Problems The last slide contains some great architectural components, but used non- optimally they can come with a few problems: Can single modules Can single modules How much of this is exist on their own be tested instantly re-usable? independently? independently?Thursday, 6 October 2011
  54. Possible Problems Some further concerns: How much do Is your application If speci c parts of modules depend on tightly coupled? your app fail, can it others in the system? still function?Thursday, 6 October 2011
  55. Think Long-Term What future concerns haven’t been factored in to this architecture? • You may decide to switch from using jQuery to Dojo or YUI for reasons of performance, security or design • Libraries are not easily interchangeable and have high switching costs if tightly coupled to your appThursday, 6 October 2011
  56. Ask Yourself This is important. If you reviewed your architecture right now, could a decision to switch libraries be made without rewriting your entire application?Thursday, 6 October 2011
  57. A Solution Fixing our architecture with JavaScript design patterns. “The only difference between a problem and a solution is that people understand the solution.’ - Charles F. KetteringThursday, 6 October 2011
  58. Thursday, 6 October 2011
  59. Let’s Combine Our Patterns We’re going to build something special. Module Pattern + = WIN Facade Pattern + Mediator PatternThursday, 6 October 2011
  60. Let’s Think. What do we want? Functionality broken Framework or library Loosely coupled down into smaller agnostic. Flexibility to architecture independent modules change in future.Thursday, 6 October 2011
  61. Some More Ideas. How might we achieve this? An intermediate layer Single modules speak interprets requests. Prevents apps from to the app when Modules don’t access falling over due to errors something interesting the core or libraries with speci c modules. happens directly.Thursday, 6 October 2011
  62. 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.Thursday, 6 October 2011
  63. The Application Core 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.Thursday, 6 October 2011
  64. 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.Thursday, 6 October 2011
  65. Aura: A Preview Enough talk! Let’s take a look at some real code. Aura is a framework I’m building at AOL that provides a boilerplate for one way to approach implementing this architecture. It will be released for open-source consumption once stable.Thursday, 6 October 2011
  66. Aura: Core The Mediator / Application Core • Swappable Mediator with a light wrapper around a speci c JavaScript library • Ability to start and stop modules • By default it comes with wrappers for both Dojo and jQuery, with core syntax that resembles the latterThursday, 6 October 2011
  67. Aura: Core How does this work? • Accessing this wrapper, the facade doesn’t care what framework has been slotted in. It works with the abstraction • Behind the scenes, arguments are mapped to the relevant jQuery or dojo methods and signatures for achieving speci c behaviourThursday, 6 October 2011
  68. Aura: Core A sample of the method signatures and namespaces supported // some core methods core.start(module_id);   // define and initialise a module core.startAll();         // define, initialise all modules core.stop(module_id);    // stop a specific module core.stopAll();          // stop all modules core.destroy(module_id); // destroy a specific module core.destroyAll();       // destroy all modules // core namespaces core.events  // bind, unbind etc. core.utils   // type checking. core.dom     // css, DOM manipulationThursday, 6 October 2011
  69. Aura: Core.dom > Chaining, CSS Chaining and CSS Style Manipulation are both supported. Behind the scenes, this works with both jQuery and Dojo, providing a single abstracted API that’s familiar to users. // Chaining and CSS style manipulation aura.core.dom.query(body).css({background:#1c1c1c}); aura.core.dom.query(#search_input).css({background:blue}).css({color:pink}); aura.core.dom.query(#search_button).css({width:200,height:100}); // Manipulating styles within a context aura.core.dom.css(body, {background:red}); aura.core.dom.css(#shopping-cart,{color:green,background:yellow}); aura.core.dom.css(#product-panel li, {background:purple}); // Passing in DOM nodes also works var test = aura.core.dom.query(#shopping-cart); //.query should handle this. aura.core.dom.css(test, {background:purple});Thursday, 6 October 2011
  70. Aura: Core.dom > Attribs, Anim Attribute manipulation and animation are also abstracted using an API similar to jQuery. Remember, with Dojo this actually maps arguments back to the relevant Dojo methods needed to achieve the task. // Get and set attributes console.log(aura.core.dom.query(#seach_input).attr(title,foobar)); console.log(aura.core.dom.query(#search_input).attr(title)); // Passing in DOM nodes var q = aura.core.dom.query(#shopping-cart); console.log(aura.core.dom.attr(q, id)); // Animation support aura.core.dom.animate(#product-panel li, { width: 400, height:20}, 5000); aura.core.dom.animate(button, {width: 200, duration: 100}); aura.core.dom.animate(p, {width:20, height:40, padding:10,duration:200});Thursday, 6 October 2011
  71. Aura: Core.dom > Create, Ajax Similarly, element creation and ajax are also supported in the abstracted core interface. // Element creation var el = aura.core.dom.create("a", {          href: "foo.html",          title: "bar!",          innerHTML: "link"  },  body); // XHR/Ajax requests (deferred support coming soon)  aura.core.dom.ajax({          url:index.html,          type:get, //post, put          dataType: "text",          success:function(data){                  console.log(success);          },          error:function(){                  console.log(error);          }  });  Thursday, 6 October 2011
  72. Aura: Aura.f (Facade) A very lightweight implementation of the facade pattern that provides modules with limited access to the core. They must communicate through the facade.  aura.f = {     define:function( core, module, config ){                 var core = aura.core, dom = core.dom, events =core.events,         component = core.dom.query(module)._elements;         return {             publish:function( e ){                 events.trigger(e);             },             subscribe:function( e ){                 events.register(e, module);             },             query:function( selector ){                 return component.query(selector)._elements;             },             bind:function( el , type, fn ){                 dom.bind(el, type, fn);             },             unbind:function( el , type, fn ){                 dom.unbind(el, type, fn);             },             Thursday, 6 October 2011
  73. Aura: Modules > add-todo.js Module wireframe. aura.core.define("#todo-list", function (f) {     var todos;          return {         init : function () {           /*..*/         },         destroy : function () { Let’s focus on this.          /*..*/        },        addEntry : function (todo) {          /*..*/        }    }; });Thursday, 6 October 2011
  74. Aura: Modules > add-todo.js Module for adding new Todo items to a container on a page init : function () {     todos = f.query("ul");     f.subscribe({         add-todo : this.addEntry             }); }, destroy : function () {     f.destroy(todos); }, addEntry : function (todo) {     var entry = f.create("li", { class : todo_entry, [                     f.create("span", { class :todo_text, text : todo.value }),                     f.create("span", { class :todo_date, text : todo.date })                 ]});     todos.append(entry);          f.publish({             type : added-todo,             data : todo.value     });                }Thursday, 6 October 2011
  75. Aura: Modules > add-todo.js Note how modules are only concerned with publishing and subscripting to noti cations from the rest of the application. They don’t touch other modules directly. init : function () {     todos = f.query("ul"); 1. Cache the <ul> for a component representing the todo list (eg. a div)     f.subscribe({ 2. Subscribe to noti cations about a new todo item being available. (eg. a         add-todo : this.addEntry         just clicked ‘add’ somewhere in the app) user has     }); 3. A new noti cation will trigger our .addEntry() method }, destroy : function () {     f.destroy(todos); }, addEntry : function (todo) {     var entry = f.create("li", { class : todo_entry, [                     f.create("span", { class :todo_text, text : todo.value }),                     f.create("span", { class :todo_date, text : todo.date })                 ]});     todos.append(entry);          f.publish({             type : added-todo,             data : todo.value     });                }Thursday, 6 October 2011
  76. Aura: Modules > add-todo.js The facade allows access to everything from DOM query methods to dynamic object creation. It can be as light or as heavy on feature-access as you wish. init : function () {     todos = f.query("ul");     f.subscribe({         add-todo : this.addEntry             }); }, destroy : function () {     f.destroy(todos); 1. Dynamically create a new todo entry (a list element with child spans }, for the Todo text and creation date) 2. Append this to the existing todo list cached earlier addEntry : function (todo) {     var entry = f.create("li", { class : todo_entry, [                     f.create("span", { class :todo_text, text : todo.value }),                     f.create("span", { class :todo_date, text : todo.date })                 ]});     todos.append(entry);           f.publish({             type : added-todo,             data : todo.value     });                }Thursday, 6 October 2011
  77. Aura: Modules > add-todo.js Module for adding new Todo items to a container on a page init : function () {     todos = f.query("ul");     f.subscribe({         add-todo : this.addEntry             }); }, destroy : function () {     f.destroy(todos); }, addEntry : function (todo) {     var entry = f.create("li", { class : todo_entry,children : [                     f.create("span", { class :todo_text, text : todo.value }),                     f.create("span", { class :todo_date, text : todo.date })                 ]});     todos.append(entry);          f.publish({ Publish a noti cation letting other modules know a todo             type : added-todo,             data : todo.value item has been added. The application can then react     });   accordingly to this action.              }Thursday, 6 October 2011
  78. Aura: Modules > counter.js And here’s a basic module that consumes the noti cations from the last one. aura.core.define("todo-counter", function(f){     var count, counter;     counter = f.query(".counter-text")          return{         init : function(){             f.subscribe({                 added-todo : this.updateCount; Consuming events             });         },         destroy: function(){             f.destroy(count);         },         updateCount: function(e){             count++;             counter.html(count); Using library features             f.publish({                type: counter-updated, without directly touching them                data: count or the application core.             });         }     } });Thursday, 6 October 2011
  79. What We Learned Let’s review what we looked at today. ‘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 FordThursday, 6 October 2011
  80. Summary Today we learned how to use three design patterns to create scalable ‘future- proof’ application architectures. The idea is to have: Application core Facade Modules Mediator Core abstraction Highly decoupled Module manager Permission manager Unique blocks Swappable Framework agnosticThursday, 6 October 2011
  81. That’s it. For more on this architecture and other topics, check out: Blog Twitter GitHub http://addyosmani.com @addyosmani /addyosmaniThursday, 6 October 2011
  82. Thursday, 6 October 2011

×