SlideShare a Scribd company logo
1 of 139
Download to read offline
JavaScript Patterns




    Giordano Scalzo
Wednesday, November 10, 2010
I’m not a guru!




Wednesday, November 10, 2010
I’m still learning




Wednesday, November 10, 2010
Why?




Wednesday, November 10, 2010
JavaScript isn’t this anymore




Wednesday, November 10, 2010
JavaScript is everywhere!




Wednesday, November 10, 2010
JavaScript is trendy!


            Technology Radar




Wednesday, November 10, 2010
JavaScript is trendy!


            Technology Radar




Wednesday, November 10, 2010
At the beginning...




Wednesday, November 10, 2010
Hacked by Brendan Eich in one week...




Wednesday, November 10, 2010
Former Mocha, renamed to JavaScript by Netscape




Wednesday, November 10, 2010
after a while...




Wednesday, November 10, 2010
and...




Wednesday, November 10, 2010
:-(




Wednesday, November 10, 2010
and so...




Wednesday, November 10, 2010
Back to study!




Wednesday, November 10, 2010
Started a notebook...




Wednesday, November 10, 2010
Essential
                                  Scope




Wednesday, November 10, 2010
function sum(x, y){
                                   // implied global
                                   result = x + y;
                                   return result;
                               }




{antipattern}
Wednesday, November 10, 2010
Global variables are evil!




Wednesday, November 10, 2010
Variables clash




Wednesday, November 10, 2010
Always declare variables with var



                                      function sum(x, y){
                                      	 var result = x + y;
                                         return result;
                                      }




{pattern}
Wednesday, November 10, 2010
function foo(){
                                   var a = b = 0;
                                   //...
                               }




{antipattern}
Wednesday, November 10, 2010
b become global




                               function foo(){
                                   var a = (b = 0);
                                   //...
                               }




{antipattern}
Wednesday, November 10, 2010
don’t use assign chain in definition




                               function foo(){
                                   var a, b;
                                   a = b = 0;
                                   //...
                               }




{pattern}
Wednesday, November 10, 2010
Single var pattern


                                function func(){
                                    var a = 1,
                                  	 b = 2,
                                  	 sum = a + b,
                                  	 myobject = {},
                                  	 i,
                                  	 j;
                                    // function body...
                                }




{pattern}
Wednesday, November 10, 2010
Don’t forget comma otherwise...




Wednesday, November 10, 2010
... variables become globals




Wednesday, November 10, 2010
Hoisting


                               myname = "global"; // global variable
                               function func(){
                               	 // code...
                                   console.log(myname); // "undefined"

                                   // code...
                                   var myname = "local";
                                   console.log(myname); // "local"
                               }

                               func();




{antipattern}
Wednesday, November 10, 2010
Hoisting


                               myname = "global"; // global variable
                               function func(){
                                   var myname = "declared";
                               	 // code...
                                   console.log(myname); // "declared"

                                   // code...
                                   myname = "local";
                                   console.log(myname); // "local"
                               }

                               func();




{pattern}
Wednesday, November 10, 2010
Against minimum vertical distance
                               principle


              “Variables should be declared as close to
              their usage as possible”
                                Robert C. Martin - Clean Code



Wednesday, November 10, 2010
Essential
                               Literal and Constructor




Wednesday, November 10, 2010
In JavaScript almost everything is an object




Wednesday, November 10, 2010
It’s easy...



                               var person = new Object();
                               person.name = "Scott";
                               person.say = function(){
                                   return "I am " + this.name;
                               };

                               console.log(person.say());




Wednesday, November 10, 2010
but wrong! :-(



                               var person = new Object();
                               person.name = "Scott";
                               person.say = function(){
                                   return "I am " + this.name;
                               };

                               console.log(person.say());




{antipattern}
Wednesday, November 10, 2010
var person = {};
                               person.name = "Scott";
                               person.say = function(){
                                   return "I am " + this.name;
                               };

                               console.log(person.say());




{pattern}
Wednesday, November 10, 2010
What if we need similar objects...

                          var person = {};
                          person.name = "Scott";
                          person.say = function(){
                              return "I am " + this.name;
                          };
                          console.log(person.say()); // I am Scott

                          var otherPerson = {};
                          otherPerson.name = "Tiger";
                          otherPerson.say = function(){
                              return "I am " + this.name;
                          };

                          console.log(otherPerson.say()); // I am Tiger




Wednesday, November 10, 2010
A lot of duplication

                          var person = {};
                          person.name = "Scott";
                          person.say = function(){
                              return "I am " + this.name;
                          };
                          console.log(person.say()); // I am Scott

                          var otherPerson = {};
                          otherPerson.name = "Tiger";
                          otherPerson.say = function(){
                              return "I am " + this.name;
                          };

                          console.log(otherPerson.say()); // I am Tiger




Wednesday, November 10, 2010
Duplication is evil!




Wednesday, November 10, 2010
Custom Constructor Functions



                               var Person = function(name){
                                   this.name = name;
                                   this.say = function(){
                                       return "I am " + this.name;
                                   }
                               }
                               var person = new Person("Scott");

                               console.log(person.say()); // I am Scott




{pattern}
Wednesday, November 10, 2010
Behind the scenes...



                               var Person = function(name){
                                   // var this = {};
                                   this.name = name;
                                   this.say = function(){
                                       return "I am " + this.name;
                                   };
                                   // return this;
                               };




{pattern}
Wednesday, November 10, 2010
So, at the end...

                               var Person = function(name){
                                   this.name = name;
                                   this.say = function(){
                                       return "I am " + this.name;
                                   };
                               };

                               var scott = new Person('Scott');
                               var tiger = new Person('Tiger');

                               console.log(scott.say());
                               console.log(tiger.say());




{pattern}
Wednesday, November 10, 2010
What if we forget new?




Wednesday, November 10, 2010
this will point to global object

                           var Person = function(name){
                               this.name = name;
                               this.say = function(){
                                   return "I am " + this.name;
                               };
                           };

                           var scott = new Person('Scott')
                           var adam = Person('Adam')

                           console.log(typeof scott); //object
                           console.log(scott.name); // Scott
                           console.log(typeof adam); //'undefined'
                           console.log(window.name); // Adam




Wednesday, November 10, 2010
Enforce new pattern one: naming convention




Wednesday, November 10, 2010
var Person = function(name){
                                   var that = {};
                                   that.name = name;
                                   that.say = function(){
                                       return "I am " + that.name;};
                                   return that;
                               };

                               var scott = new Person('Scott')
                               var adam = Person('Adam')

                               console.log(typeof scott); //Object
                               console.log(scott.name); // Scott

                               console.log(typeof adam); //Object
                               console.log(adam.name); // Adam



{pattern}
Wednesday, November 10, 2010
Drawback: we loose prototype reference :-(

                          var Person = function(name){
                              var that = {};
                              that.name = name;
                              that.say = function(){
                                  return "I am " + that.name;
                              };
                              return that;
                          };

                          Person.prototype.iamhumanbeing = true;

                          var scott = new Person('Scott')
                          var adam = Person('Adam')

                          console.log(scott.iamhumanbeing); // undefined
                          console.log(adam.iamhumanbeing); // undefined




Wednesday, November 10, 2010
Interm!zo

                                Prototype property




Wednesday, November 10, 2010
Define ancestors chain




                               var foo = {one: 1, two: 2};
                               var bar = {three: 3};
                               foo.__proto__ = bar;
                               console.log(foo.one);
                               console.log(foo.three);




Wednesday, November 10, 2010
bar
                                        three: 3



                                foo
                               one: 1
                               two: 2
                      __proto__

Wednesday, November 10, 2010
Behind the scenes...



                          var Person = function(name){
                              // this.prototype = {constructor: this}
                              var that = {};
                              that.name = name;
                              that.say = function(){
                                  return "I am " + that.name;
                              };
                              return that;
                          };




Wednesday, November 10, 2010
Self invoking constructor
                               var Person = function(name){
                                   if (this instanceof Person) {
                                       this.name = name;
                                       this.say = function(){
                                           return "I am " + that.name;
                                       }
                                   }
                                   else {
                                       return new Person(name);
                                   }
                               };
                               Person.prototype.iamhumanbeing = true;
                               var scott = new Person('Scott')
                               var adam = Person('Adam')
                               console.log(scott.name); // Scott
                               console.log(adam.name); // Adam
                               console.log(scott.iamhumanbeing); // true
                               console.log(adam.iamhumanbeing); // true


{pattern}
Wednesday, November 10, 2010
Essential
                                  Functions




Wednesday, November 10, 2010
Functions as first class objects




Wednesday, November 10, 2010
Immediate functions




                                (function(){
                                    alert('watch out!');
                                })();




Wednesday, November 10, 2010
Initialization pattern




                               (function(){
                                   var days = ['Sun', 'Mon', 'Tue', 'Wed',
                               	              'Thu', 'Fri', 'Sat'],
                               	     today = new Date(),
                               	 	 msg = 'Today is ' +
                               	 	        days[today.getDay()] +
                               	 	 	    ', ' +
                               	 	 	    today.getDate();
                                   console.log(msg);
                               })(); // "Today is Wed, 10"




{pattern}
Wednesday, November 10, 2010
Function scope




Wednesday, November 10, 2010
5 globals...
                               // constructors
                               function Parent(){
                               }

                               function Child(){
                               }

                               // a variable
                               var some_var = 1;
                               // some objects
                               var module1 = {};
                               module1.data = {
                                   a: 1,
                                   b: 2
                               };
                               var module2 = {};



{antipattern}
Wednesday, November 10, 2010
1 global!
                         // global object
                         var MYAPP = (function(){
                             var my = {};
                                                           {pattern}
                             // constructors
                             my.Parent = function(){};
                             my.Child = function(){};
                             // a variable
                             my.some_var = 1;
                             // an object container
                             my.modules = {};
                             // nested objects
                             my.modules.module1 = {};
                             my.modules.module1.data = {
                                 a: 1,
                                 b: 2
                             };
                             my.modules.module2 = {};
                             return my;
                         })();

                         console.log(MYAPP.modules.module1.data.a); // 1

Wednesday, November 10, 2010
What about encapsulation?




Wednesday, November 10, 2010
function Gadget(){
                       this.name = 'iPod';
                       this.stretch = function(){
                           return 'iPad';
                       }
                   };

                   var toy = new Gadget();
                   console.log(toy.name); // `iPod`
                   toy.name = 'Zune'
                   console.log(toy.name); // `Zune` is public
                   console.log(toy.stretch()); // stretch() is public




{antipattern}
Wednesday, November 10, 2010
Create private member


                               function Gadget(){
                                   var name = 'iPod';
                                   this.getName = function(){
                                       return name;
                                   }
                               };

                               var toy = new Gadget();
                               console.log(toy.getName()); // `iPod`
                               toy.name = 'Zune'
                               console.log(toy.getName()); // `iPod`




{pattern}
Wednesday, November 10, 2010
for methods too
                               function Gadget() {
                                   var name = 'iPod';
                                   var upgrade = function(){
                                       return 'iPhone';
                                   }

                                    this.getName = function () {
                                        return name;
                                    }
                                    this.pay = function() {
                                        return upgrade();
                                    }
                               };

                               var toy = new Gadget();
                               console.log(toy.pay()); // `iPhone`
                               console.log(toy.upgrade()); // `error`



{pattern}
Wednesday, November 10, 2010
Advanced
                               Code reuse patterns




Wednesday, November 10, 2010
Classical vs prototypal inheritance




                                             vs

Wednesday, November 10, 2010
Classical inheritance
                               function Parent(name){
                                   this.name = name;
                               };

                               Parent.prototype.say = function(){
                                   return 'My name is ' + this.name;
                               };

                               function Child(name){
                                   this.name = name;
                               };

                               inherit(Child, Parent);

                               var dad = new Parent('Larry');
                               var kid = new Child('Scott');

                               console.log(dad.say()); // 'My name is Larry'
                               console.log(kid.say()); // 'My name is Scott'


Wednesday, November 10, 2010
function(){
                                                  return 'My name is ' + this.name;
                                              };
                                                        Parent.prototype
                                                             say()




                               new Parent()
                                name: Larry
                                __proto__


                                      console.log(dad.say());


Wednesday, November 10, 2010
Default Classical Inheritance pattern




                                      function inherit(C, P) {
                                          C.prototype = new P();
                                      };




Wednesday, November 10, 2010
function(){
                                           return 'My name is ' + this.name;
                                       };
                                                 Parent.prototype
                                                      say()




                                            new Parent()
                    new Child()              name: Larry
                    name: Scott              __proto__
                    __proto__

             console.log(kid.say());
Wednesday, November 10, 2010
Drawback: it doesn’t call parent constructor
                               function Parent(name){
                                   this.name = name;
                               };

                               Parent.prototype.say = function(){
                                   return 'My name is ' + this.name;
                               };

                               function Child(name){
                                   this.name = name;
                               };

                               inherit(Child, Parent);

                               var dad = new Parent('Larry');
                               var kid = new Child('Scott');

                               console.log(dad.say()); // 'My name is Larry'
                               console.log(kid.say()); // 'My name is Scott'


Wednesday, November 10, 2010
Drawback: it doesn’t call parent constructor
                     function Parent(name){
                         this.name = name;
                     };

                     Parent.prototype.say = function(){
                         return 'My name is ' + this.name;
                     };

                     function Child(name){ };

                     function inherit(C, P) {
                         C.prototype = new P();
                     };

                     inherit(Child, Parent);

                     var kid = new Child('Scott');

                     console.log(kid.say()); // 'My name is undefined'


Wednesday, November 10, 2010
Pattern Extension: rent a constructor




                               function Child(name){
                                   Parent.apply(this, arguments);
                               };




Wednesday, November 10, 2010
Pattern Extension: rent a constructor
                       function Parent(name){
                           this.name = name;
                       };
                       Parent.prototype.say = function(){
                           return 'My name is ' + this.name;
                       };

                       function Child(name){
                           Parent.apply(this, arguments);
                       };

                       function inherit(C, P){
                           C.prototype = new P();
                       };
                       inherit(Child, Parent);
                       var dad = new Parent('Larry');
                       var kid = new Child('Scott');
                       console.log(dad.say()); // 'My name is Larry'
                       console.log(kid.say()); // 'My name is Scott'

Wednesday, November 10, 2010
Drawback: parent constructor is called twice
                       function Parent(name){
                           this.name = name;
                       };
                       Parent.prototype.say = function(){
                           return 'My name is ' + this.name;
                       };

                       function Child(name){
                           Parent.apply(this, arguments);
                       };

                       function inherit(C, P){
                           C.prototype = new P();
                       };
                       inherit(Child, Parent);
                       var dad = new Parent('Larry');
                       var kid = new Child('Scott');
                       console.log(dad.say()); // 'My name is Larry'
                       console.log(kid.say()); // 'My name is Scott'

Wednesday, November 10, 2010
Drawback: parent constructor is called twice
                       function Parent(name){
                           this.name = name;
                       };
                       Parent.prototype.say = function(){
                           return 'My name is ' + this.name;
                       };

                       function Child(name){
                           Parent.apply(this, arguments);
                       };

                       function inherit(C, P){
                           C.prototype = new P();
                       };
                       inherit(Child, Parent);
                       var dad = new Parent('Larry');
                       var kid = new Child('Scott');
                       console.log(dad.say()); // 'My name is Larry'
                       console.log(kid.say()); // 'My name is Scott'

Wednesday, November 10, 2010
Drawback: parent constructor is called twice
                       function Parent(name){
                           this.name = name;
                       };
                       Parent.prototype.say = function(){
                           return 'My name is ' + this.name;
                       };

                       function Child(name){
                           Parent.apply(this, arguments);
                       };

                       function inherit(C, P){
                           C.prototype = new P();
                       };
                       inherit(Child, Parent);
                       var dad = new Parent('Larry');
                       var kid = new Child('Scott');
                       console.log(dad.say()); // 'My name is Larry'
                       console.log(kid.say()); // 'My name is Scott'

Wednesday, November 10, 2010
mmmm let’s try with the same prototype




Wednesday, November 10, 2010
Share the same prototype




                               function inherit(C, P){
                                   C.prototype = P.prototype;
                               };




Wednesday, November 10, 2010
Parent.prototype
                                       say()




                    new Child()                      new Parent()
                    name: Scott                       name: Larry
                    __proto__                         __proto__



Wednesday, November 10, 2010
Share the same prototype




                               Inheritance works as expected
                               Constructor called only once
                               Low memory footprint




Wednesday, November 10, 2010
Share the same prototype




                               Child objects can affect other objects




Wednesday, November 10, 2010
Enhance the pattern: temporary constructor




                               function inherit(C, P) {
                                   var F = function () {};
                                   F.prototype = P.prototype;
                                   C.prototype = new F();
                               };




Wednesday, November 10, 2010
Parent.prototype
                                    say()
            new Parent()                            new F()
             name: Larry                           __proto__
             __proto__




                                         new Child()
                                         name: Scott
                                         __proto__
Wednesday, November 10, 2010
The Holy Grail Pattern of classical inheritance




                               function inherit(C, P) {
                                   var F = function () {};
                                   F.prototype = P.prototype;
                                   C.prototype = new F();
                                   C.uber = P.prototype;
                                   C.prototype.constructor = C;
                               };




Wednesday, November 10, 2010
We got it!




Wednesday, November 10, 2010
What about Prototypal Inheritance?




Wednesday, November 10, 2010
No more classes, only objects




Wednesday, November 10, 2010
What we want in prototypal inheritance



                               var parent = {
                                   name: "Larry",
                                   say: function(){
                                       return "My name is " + this.name;
                                   }
                               };

                               var child = object(parent);
                               child.name = 'Scott'

                               console.log(child.say()); // "Scott"




Wednesday, November 10, 2010
Prototypal inheritance function




                                      function object(o) {
                                          function F() {}
                                          F.prototype = o;
                                          return new F();
                                      };




Wednesday, November 10, 2010
parent
                               name: Scott
                                  say()




                                             child = new F()
                                               name: Larry
                                               __proto__



Wednesday, November 10, 2010
With constructor function


                               var Parent = function(name){
                                   this.name = name;
                                   this.say = function(){
                                       return "My name is " + this.name;
                                   }
                               };

                               var child = object(new Parent("Larry"));
                               child.name = 'Scott'

                               console.log(child.say()); // "Scott"




Wednesday, November 10, 2010
better classical or prototypal?




Wednesday, November 10, 2010
It depends




Wednesday, November 10, 2010
Goals of inheritance is reuse and reduce duplication




Wednesday, November 10, 2010
isA relationship...
                        Liskov principle...
                  difficult to tame inheritance...




Wednesday, November 10, 2010
A modern and better approach is to use


                                   Mix-In




Wednesday, November 10, 2010
A beahviour...


                               var Serializer = function () {};
                               Serializer.prototype = {
                                   serialize: function () {
                                       var output = [];
                                       for (key in this) {
                                           // append this[key] to output
                               	 	 	      // ...
                                       }
                                       return output.join(', ');
                                   }
                               };




Wednesday, November 10, 2010
another beahviour...


                       var XmlBuilder = function () {};
                       XmlBuilder.prototype = {
                           toXml: function () {
                               var output = '';
                               for (key in this) {
                                    // append xml of this[key] to output
                                    // ...
                               }
                               return output;
                           }
                       };




Wednesday, November 10, 2010
and an object...



                               var Author = function (name, books) {
                                   this.name = name || "";
                                   this.books = books || [];
                               }




Wednesday, November 10, 2010
result!
       augment(Author, Serializer);
       augment(Author, XmlBuilder);

       var author = new Author('Umberto Eco',
                               ['Il nome della rosa',
                                'Il Pendolo di Foucault']);
       var serializedString = author.serialize();
       console.log(serializedString); // name: Umberto Eco,
                                       // books: Il nome della rosa,
                                      // Il Pendolo di Foucault
       var xmlString = author.toXml();
       console.log(xmlString); //<name>Umberto Eco</name>
                               // <book>Il nome della rosa</book>
       	 	 	 	 	 	             // <book>Il Pendolo di Focault</book>




Wednesday, November 10, 2010
The recipe



                  function augment(receivingClass, givingClass) {
                      for (methodName in givingClass.prototype) {
                          if (!receivingClass.prototype[methodName]) {
                              receivingClass.prototype[methodName] =
                               givingClass.prototype[methodName];
                          }
                      }
                  }




Wednesday, November 10, 2010
Advanced
                               Design Patterns




Wednesday, November 10, 2010
Wednesday, November 10, 2010
“A design pattern is a
                               general reusable solution to
                               a commonly occurring
                               problem”




Wednesday, November 10, 2010
JavaScript is not J@#*!




Wednesday, November 10, 2010
Factory pattern
                  creation of objects
                  subclasses decide which class to instantiate




Wednesday, November 10, 2010
var BicycleFactory = {
      createBicycle: function(model){
          var bicycle;
          switch (model) {
              case 'The Speedster':
                  bicycle = new Speedster();
                  break;
              case 'The Lowrider':
                  bicycle = new Lowrider();
                  break;
              case 'The Comfort Cruiser':
              default:
                  bicycle = new ComfortCruiser();
          }
          Interface.ensureImplements(bicycle, Bicycle);
          bicycle.assemble();
          bicycle.wash();
          return bicycle;
      }
  };
  var californiaCruisers = new BicycleFactory();
  var yourNewBike = californiaCruisers.createBicycle('The Speedster');

Wednesday, November 10, 2010
A more concrete example...

     var XMLHttpFactory = function(){
         this.createXMLHttp = function(){
             if (typeof XMLHttpRequest !== "undefined") {
                  return XMLHttpRequest();
             }
             else
                  if (typeof window.ActiveXObject !== "undefined") {
                      return ActiveXObject("MSXML2.XMLHttp");
                  }
                  else {
                      alert("XHR Object not in production");
                  }
         }
     };

     var xhr = new XMLHttpFactory().createXMLHttp();




Wednesday, November 10, 2010
It seems lightly broken....




Wednesday, November 10, 2010
var XMLHttpFactory = function(){
         this.createXMLHttp = function(){
             if (typeof XMLHttpRequest !== "undefined") {
                  return XMLHttpRequest();
             }
             else
                  if (typeof window.ActiveXObject !== "undefined") {
                      return ActiveXObject("MSXML2.XMLHttp");
                  }
                  else {
                      alert("XHR Object not in production");
                  }
         }
     };

     var xhr = new XMLHttpFactory().createXMLHttp();




Wednesday, November 10, 2010
Chain of Responsibility pattern




Wednesday, November 10, 2010
Extract condition and action....



                       var XhrStandard = function(){
                            this.canHandle = function(){
                              return typeof XMLHttpRequest !== "undefined";
                            }

                               this.xhr = function(){
                                 return XMLHttpRequest();
                               }
                         };




Wednesday, November 10, 2010
another condition and action....




                         var XhrIe = function(){
                             this.canHandle = function(){
                               return typeof ActiveXObject !== "undefined";
                             }
                            this.xhr = function(){
                               return ActiveXObject("MSXML2.XMLHttp");
                             }
                         };




Wednesday, November 10, 2010
and last one condition and action....




                               var XhrError = function(){
                                   this.canHandle = function(){
                                     return true;
                                   }
                                  this.xhr = function(){
                                     throw("XHR Object not in production");
                                   }
                               };




Wednesday, November 10, 2010
and the engine!
                var XMLHttpFactory = function(){
                    //... ChainLinks...
                    var creators = [new XhrStandard(),
                                    new XhrIe(),
                                    new XhrError()];

                         this.createXMLHttp = function(){
                                 var creator;
                                 for(var i = 0; i < creators.length; ++i){
                                     creator = creators[i];
                                     if(creator.canHandle()) {
                                         return creator.xhr();
                                     }
                                 }
                         }
                };

                var xhr = new XMLHttpFactory().createXMLHttp();
                console.log(xhr);



Wednesday, November 10, 2010
Or following the book...




Wednesday, November 10, 2010
Refactored an action...
                   var XhrStandard = function(){
                       this.canHandle = function(){
                           return typeof XMLHttpRequest !== "undefined";
                       }

                               this.xhr = function(){
                                   if (this.canHandle()) {
                                       return XMLHttpRequest();
                                   }
                                   return this.successor.xhr();
                               }

                               this.addSuccessor = function(successor){
                                   this.successor = successor;
                                   return this.successor;
                               }
                   };




Wednesday, November 10, 2010
other action...
                      var XhrIe = function(){
                          this.canHandle = function(){
                              return typeof ActiveXObject !== "undefined";
                          }
                          this.xhr = function(){
                              if (this.canHandle()) {
                                  return ActiveXObject("MSXML2.XMLHttp");
                              }
                              return this.successor.xhr();
                          }

                               this.addSuccessor = function(successor){
                                   this.successor = successor;
                                   return this.successor;
                               }
                      };




Wednesday, November 10, 2010
last action...


                         var XhrError = function(){
                             this.canHandle = function(){
                                 return true;
                             }
                             this.xhr = function(){
                                 throw ("XHR Object not in production");
                             }
                             this.addSuccessor = function(successor){
                                 this.successor = successor;
                                 return this.successor;
                             }
                         };




Wednesday, November 10, 2010
and the engine!
                   var XMLHttpFactory = function(){
                     //... ChainLinks...

                               var creator = (function(){
                                   var head = new XhrIe();
                                   head.addSuccessor(new XhrStandard())
                                       .addSuccessor(new XhrError());
                                   return head;
                               })();

                               this.createXMLHttp = function(){
                                   return creator.xhr();
                               }
                   };

                   var xhr = new XMLHttpFactory().createXMLHttp();
                   console.log(xhr);




Wednesday, November 10, 2010
mmm duplication...




Wednesday, November 10, 2010
Same for all...
                      var XhrIe = function(){
                          this.canHandle = function(){
                              return typeof ActiveXObject !== "undefined";
                          }
                          this.xhr = function(){
                              if (this.canHandle()) {
                                  return ActiveXObject("MSXML2.XMLHttp");
                              }
                              return this.successor.xhr();
                          }

                               this.addSuccessor = function(successor){
                                   this.successor = successor;
                                   return this.successor;
                               }
                      };




Wednesday, November 10, 2010
Similar for all..
                      var XhrIe = function(){
                          this.canHandle = function(){
                              return typeof ActiveXObject !== "undefined";
                          }
                          this.xhr = function(){
                              if (this.canHandle()) {
                                  return ActiveXObject("MSXML2.XMLHttp");
                              }
                              return this.successor.xhr();
                          }

                               this.addSuccessor = function(successor){
                                   this.successor = successor;
                                   return this.successor;
                               }
                      };




Wednesday, November 10, 2010
Template Method pattern




Wednesday, November 10, 2010
Template Method pattern



                               ... and a little bit of Mix-In




Wednesday, November 10, 2010
Extracted same and similar behaviours....


                var ChainLink = function() {};
                ChainLink.prototype.exec = function(){
                       if(this.canHandle()) {
                         return this.doIt();
                       }
                       return this.successor.exec();
                    };

                         ChainLink.prototype.addSuccessor = function(successor){
                             this.successor = successor;
                             return this.successor;
                         }




Wednesday, November 10, 2010
Augment an action...



                       var XhrStandard = augment(function(){
                           this.canHandle = function(){
                              return typeof XMLHttpRequest !== "undefined";
                           }
                           this.doIt = function(){
                                  return XMLHttpRequest();
                           };
                       }, ChainLink);




Wednesday, November 10, 2010
another action...




                 var XhrIe = augment(function(){
                     this.canHandle = function(){
                        return typeof ActiveXObject !== "undefined";
                     }
                     this.doIt = function(){
                          return this.doIt();
                     };
                 }, ChainLink);




Wednesday, November 10, 2010
and last one.



                               var XhrError = augment(function(){
                                   this.canHandle = function(){
                                     return true;
                                   }

                                   this.doIt = function(){
                                     throw("XHR Object not in production");
                                   }
                               },ChainLink);




Wednesday, November 10, 2010
and the engine is the same!
                   var XMLHttpFactory = function(){
                     //... ChainLinks...

                               var creator = (function(){
                                   var head = new XhrIe();
                                   head.addSuccessor(new XhrStandard())
                                       .addSuccessor(new XhrError());
                                   return head;
                               })();

                               this.createXMLHttp = function(){
                                   return creator.xhr();
                               }
                   };

                   var xhr = new XMLHttpFactory().createXMLHttp();
                   console.log(xhr);




Wednesday, November 10, 2010
It’s just a beginning...




Wednesday, November 10, 2010
peep code


Wednesday, November 10, 2010
Study




Wednesday, November 10, 2010
Wednesday, November 10, 2010
Wednesday, November 10, 2010
“Save it for a rainy day!”




Wednesday, November 10, 2010
Check your code with jslint.com




Wednesday, November 10, 2010
Wednesday, November 10, 2010
giordano.scalzo@cleancode.it
                               @giordanoscalzo
                               www.slideshare.net/giordano
                               github.com/gscalzo
Wednesday, November 10, 2010

More Related Content

What's hot

ES6 - Next Generation Javascript
ES6 - Next Generation JavascriptES6 - Next Generation Javascript
ES6 - Next Generation JavascriptRamesh Nair
 
Ian 20150116 java script oop
Ian 20150116 java script oopIan 20150116 java script oop
Ian 20150116 java script oopLearningTech
 
Антон Нонко, Классические строки в C++
Антон Нонко, Классические строки в C++Антон Нонко, Классические строки в C++
Антон Нонко, Классические строки в C++Sergey Platonov
 
CodeFest 2010. Иноземцев И. — Fantom. Cross-VM Language
CodeFest 2010. Иноземцев И. — Fantom. Cross-VM LanguageCodeFest 2010. Иноземцев И. — Fantom. Cross-VM Language
CodeFest 2010. Иноземцев И. — Fantom. Cross-VM LanguageCodeFest
 
Stamps - a better way to object composition
Stamps - a better way to object compositionStamps - a better way to object composition
Stamps - a better way to object compositionVasyl Boroviak
 
What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)Pavlo Baron
 
The Ring programming language version 1.7 book - Part 83 of 196
The Ring programming language version 1.7 book - Part 83 of 196The Ring programming language version 1.7 book - Part 83 of 196
The Ring programming language version 1.7 book - Part 83 of 196Mahmoud Samir Fayed
 
Rust Mozlando Tutorial
Rust Mozlando TutorialRust Mozlando Tutorial
Rust Mozlando Tutorialnikomatsakis
 
The mighty js_function
The mighty js_functionThe mighty js_function
The mighty js_functiontimotheeg
 
JavaScript - Like a Box of Chocolates
JavaScript - Like a Box of ChocolatesJavaScript - Like a Box of Chocolates
JavaScript - Like a Box of ChocolatesRobert Nyman
 
Rust concurrency tutorial 2015 12-02
Rust concurrency tutorial 2015 12-02Rust concurrency tutorial 2015 12-02
Rust concurrency tutorial 2015 12-02nikomatsakis
 
Clojure: Practical functional approach on JVM
Clojure: Practical functional approach on JVMClojure: Practical functional approach on JVM
Clojure: Practical functional approach on JVMsunng87
 
Introduction into ES6 JavaScript.
Introduction into ES6 JavaScript.Introduction into ES6 JavaScript.
Introduction into ES6 JavaScript.boyney123
 
JS Level Up: Prototypes
JS Level Up: PrototypesJS Level Up: Prototypes
JS Level Up: PrototypesVernon Kesner
 

What's hot (18)

ES6 - Next Generation Javascript
ES6 - Next Generation JavascriptES6 - Next Generation Javascript
ES6 - Next Generation Javascript
 
Ian 20150116 java script oop
Ian 20150116 java script oopIan 20150116 java script oop
Ian 20150116 java script oop
 
Антон Нонко, Классические строки в C++
Антон Нонко, Классические строки в C++Антон Нонко, Классические строки в C++
Антон Нонко, Классические строки в C++
 
CodeFest 2010. Иноземцев И. — Fantom. Cross-VM Language
CodeFest 2010. Иноземцев И. — Fantom. Cross-VM LanguageCodeFest 2010. Иноземцев И. — Fantom. Cross-VM Language
CodeFest 2010. Иноземцев И. — Fantom. Cross-VM Language
 
Rust-lang
Rust-langRust-lang
Rust-lang
 
Stamps - a better way to object composition
Stamps - a better way to object compositionStamps - a better way to object composition
Stamps - a better way to object composition
 
Groovy
GroovyGroovy
Groovy
 
Rust言語紹介
Rust言語紹介Rust言語紹介
Rust言語紹介
 
What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)
 
The Ring programming language version 1.7 book - Part 83 of 196
The Ring programming language version 1.7 book - Part 83 of 196The Ring programming language version 1.7 book - Part 83 of 196
The Ring programming language version 1.7 book - Part 83 of 196
 
Rust Mozlando Tutorial
Rust Mozlando TutorialRust Mozlando Tutorial
Rust Mozlando Tutorial
 
The mighty js_function
The mighty js_functionThe mighty js_function
The mighty js_function
 
JavaScript - Like a Box of Chocolates
JavaScript - Like a Box of ChocolatesJavaScript - Like a Box of Chocolates
JavaScript - Like a Box of Chocolates
 
Rust concurrency tutorial 2015 12-02
Rust concurrency tutorial 2015 12-02Rust concurrency tutorial 2015 12-02
Rust concurrency tutorial 2015 12-02
 
Clojure: Practical functional approach on JVM
Clojure: Practical functional approach on JVMClojure: Practical functional approach on JVM
Clojure: Practical functional approach on JVM
 
iSoligorsk #3 2013
iSoligorsk #3 2013iSoligorsk #3 2013
iSoligorsk #3 2013
 
Introduction into ES6 JavaScript.
Introduction into ES6 JavaScript.Introduction into ES6 JavaScript.
Introduction into ES6 JavaScript.
 
JS Level Up: Prototypes
JS Level Up: PrototypesJS Level Up: Prototypes
JS Level Up: Prototypes
 

Similar to JavaScript Patterns Guidebook

Javascript the Language of the Web
Javascript the Language of the WebJavascript the Language of the Web
Javascript the Language of the Webandersjanmyr
 
Websockets, Ruby y Pusher Webprendedor 2010
Websockets, Ruby y Pusher Webprendedor 2010Websockets, Ruby y Pusher Webprendedor 2010
Websockets, Ruby y Pusher Webprendedor 2010Ismael Celis
 
The Not Java That's Not Scala
The Not Java That's Not ScalaThe Not Java That's Not Scala
The Not Java That's Not ScalaJustin Lee
 
Macruby - RubyConf Presentation 2010
Macruby - RubyConf Presentation 2010Macruby - RubyConf Presentation 2010
Macruby - RubyConf Presentation 2010Matt Aimonetti
 
MongoDB on Rails (and Ruby)
MongoDB on Rails (and Ruby)MongoDB on Rails (and Ruby)
MongoDB on Rails (and Ruby)jan_mindmatters
 
D-Talk: What's awesome about Ruby 2.x and Rails 4
D-Talk: What's awesome about Ruby 2.x and Rails 4D-Talk: What's awesome about Ruby 2.x and Rails 4
D-Talk: What's awesome about Ruby 2.x and Rails 4Jan Berdajs
 
Advanced android
Advanced androidAdvanced android
Advanced androiddonnfelker
 
Javascript the Interlingua of the Web
Javascript the Interlingua of the WebJavascript the Interlingua of the Web
Javascript the Interlingua of the Webandersjanmyr
 
Cleaner, Leaner, Meaner: Refactoring your jQuery
Cleaner, Leaner, Meaner: Refactoring your jQueryCleaner, Leaner, Meaner: Refactoring your jQuery
Cleaner, Leaner, Meaner: Refactoring your jQueryRebecca Murphey
 
The Mobile Web @ 2010 JSConf
The Mobile Web @ 2010 JSConfThe Mobile Web @ 2010 JSConf
The Mobile Web @ 2010 JSConfdion
 
Functionality Focused Code Organization
Functionality Focused Code OrganizationFunctionality Focused Code Organization
Functionality Focused Code OrganizationRebecca Murphey
 
2022 May - Shoulders of Giants - Amsterdam - Kotlin Dev Day.pdf
2022 May - Shoulders of Giants - Amsterdam - Kotlin Dev Day.pdf2022 May - Shoulders of Giants - Amsterdam - Kotlin Dev Day.pdf
2022 May - Shoulders of Giants - Amsterdam - Kotlin Dev Day.pdfAndrey Breslav
 
Objective-C for Java Developers
Objective-C for Java DevelopersObjective-C for Java Developers
Objective-C for Java DevelopersBob McCune
 
Using Templates to Achieve Awesomer Architecture
Using Templates to Achieve Awesomer ArchitectureUsing Templates to Achieve Awesomer Architecture
Using Templates to Achieve Awesomer ArchitectureGarann Means
 
ZOMG WHY IS THIS CODE SO SLOW
ZOMG WHY IS THIS CODE SO SLOWZOMG WHY IS THIS CODE SO SLOW
ZOMG WHY IS THIS CODE SO SLOWAaron Patterson
 

Similar to JavaScript Patterns Guidebook (18)

Javascript the Language of the Web
Javascript the Language of the WebJavascript the Language of the Web
Javascript the Language of the Web
 
µServices
µServicesµServices
µServices
 
Websockets, Ruby y Pusher Webprendedor 2010
Websockets, Ruby y Pusher Webprendedor 2010Websockets, Ruby y Pusher Webprendedor 2010
Websockets, Ruby y Pusher Webprendedor 2010
 
The Not Java That's Not Scala
The Not Java That's Not ScalaThe Not Java That's Not Scala
The Not Java That's Not Scala
 
Macruby - RubyConf Presentation 2010
Macruby - RubyConf Presentation 2010Macruby - RubyConf Presentation 2010
Macruby - RubyConf Presentation 2010
 
MongoDB on Rails (and Ruby)
MongoDB on Rails (and Ruby)MongoDB on Rails (and Ruby)
MongoDB on Rails (and Ruby)
 
D-Talk: What's awesome about Ruby 2.x and Rails 4
D-Talk: What's awesome about Ruby 2.x and Rails 4D-Talk: What's awesome about Ruby 2.x and Rails 4
D-Talk: What's awesome about Ruby 2.x and Rails 4
 
Advanced android
Advanced androidAdvanced android
Advanced android
 
Javascript the Interlingua of the Web
Javascript the Interlingua of the WebJavascript the Interlingua of the Web
Javascript the Interlingua of the Web
 
The jQuery Divide
The jQuery DivideThe jQuery Divide
The jQuery Divide
 
Cleaner, Leaner, Meaner: Refactoring your jQuery
Cleaner, Leaner, Meaner: Refactoring your jQueryCleaner, Leaner, Meaner: Refactoring your jQuery
Cleaner, Leaner, Meaner: Refactoring your jQuery
 
The Mobile Web @ 2010 JSConf
The Mobile Web @ 2010 JSConfThe Mobile Web @ 2010 JSConf
The Mobile Web @ 2010 JSConf
 
Functionality Focused Code Organization
Functionality Focused Code OrganizationFunctionality Focused Code Organization
Functionality Focused Code Organization
 
2022 May - Shoulders of Giants - Amsterdam - Kotlin Dev Day.pdf
2022 May - Shoulders of Giants - Amsterdam - Kotlin Dev Day.pdf2022 May - Shoulders of Giants - Amsterdam - Kotlin Dev Day.pdf
2022 May - Shoulders of Giants - Amsterdam - Kotlin Dev Day.pdf
 
Objective-C for Java Developers
Objective-C for Java DevelopersObjective-C for Java Developers
Objective-C for Java Developers
 
Meet Couch DB
Meet Couch DBMeet Couch DB
Meet Couch DB
 
Using Templates to Achieve Awesomer Architecture
Using Templates to Achieve Awesomer ArchitectureUsing Templates to Achieve Awesomer Architecture
Using Templates to Achieve Awesomer Architecture
 
ZOMG WHY IS THIS CODE SO SLOW
ZOMG WHY IS THIS CODE SO SLOWZOMG WHY IS THIS CODE SO SLOW
ZOMG WHY IS THIS CODE SO SLOW
 

More from Giordano Scalzo

The Joy Of Server Side Swift Development
The Joy Of Server Side Swift DevelopmentThe Joy Of Server Side Swift Development
The Joy Of Server Side Swift DevelopmentGiordano Scalzo
 
How to Clone Flappy Bird in Swift
How to Clone Flappy Bird in SwiftHow to Clone Flappy Bird in Swift
How to Clone Flappy Bird in SwiftGiordano Scalzo
 
A swift introduction to Swift
A swift introduction to SwiftA swift introduction to Swift
A swift introduction to SwiftGiordano Scalzo
 
Tame Accidental Complexity with Ruby and MongoMapper
Tame Accidental Complexity with Ruby and MongoMapperTame Accidental Complexity with Ruby and MongoMapper
Tame Accidental Complexity with Ruby and MongoMapperGiordano Scalzo
 
Better Software Developers
Better Software DevelopersBetter Software Developers
Better Software DevelopersGiordano Scalzo
 
Agile Iphone Development
Agile Iphone DevelopmentAgile Iphone Development
Agile Iphone DevelopmentGiordano Scalzo
 
XpUg Coding Dojo: KataYahtzee in Ocp way
XpUg Coding Dojo: KataYahtzee in Ocp wayXpUg Coding Dojo: KataYahtzee in Ocp way
XpUg Coding Dojo: KataYahtzee in Ocp wayGiordano Scalzo
 
Bdd: Tdd and beyond the infinite
Bdd: Tdd and beyond the infiniteBdd: Tdd and beyond the infinite
Bdd: Tdd and beyond the infiniteGiordano Scalzo
 
10 minutes of me: Giordano Scalzo's Visual Resume
10 minutes of me: Giordano Scalzo's Visual Resume10 minutes of me: Giordano Scalzo's Visual Resume
10 minutes of me: Giordano Scalzo's Visual ResumeGiordano Scalzo
 

More from Giordano Scalzo (12)

The Joy Of Server Side Swift Development
The Joy Of Server Side Swift DevelopmentThe Joy Of Server Side Swift Development
The Joy Of Server Side Swift Development
 
How to Clone Flappy Bird in Swift
How to Clone Flappy Bird in SwiftHow to Clone Flappy Bird in Swift
How to Clone Flappy Bird in Swift
 
A swift introduction to Swift
A swift introduction to SwiftA swift introduction to Swift
A swift introduction to Swift
 
Tame Accidental Complexity with Ruby and MongoMapper
Tame Accidental Complexity with Ruby and MongoMapperTame Accidental Complexity with Ruby and MongoMapper
Tame Accidental Complexity with Ruby and MongoMapper
 
Code kata
Code kataCode kata
Code kata
 
Tdd iPhone For Dummies
Tdd iPhone For DummiesTdd iPhone For Dummies
Tdd iPhone For Dummies
 
Better Software Developers
Better Software DevelopersBetter Software Developers
Better Software Developers
 
Agile Iphone Development
Agile Iphone DevelopmentAgile Iphone Development
Agile Iphone Development
 
XpUg Coding Dojo: KataYahtzee in Ocp way
XpUg Coding Dojo: KataYahtzee in Ocp wayXpUg Coding Dojo: KataYahtzee in Ocp way
XpUg Coding Dojo: KataYahtzee in Ocp way
 
Bdd: Tdd and beyond the infinite
Bdd: Tdd and beyond the infiniteBdd: Tdd and beyond the infinite
Bdd: Tdd and beyond the infinite
 
10 minutes of me: Giordano Scalzo's Visual Resume
10 minutes of me: Giordano Scalzo's Visual Resume10 minutes of me: Giordano Scalzo's Visual Resume
10 minutes of me: Giordano Scalzo's Visual Resume
 
Scrum in an hour
Scrum in an hourScrum in an hour
Scrum in an hour
 

Recently uploaded

What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesKari Kakkonen
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Strongerpanagenda
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...AliaaTarek5
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesThousandEyes
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 

Recently uploaded (20)

What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examples
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 

JavaScript Patterns Guidebook

  • 1. JavaScript Patterns Giordano Scalzo Wednesday, November 10, 2010
  • 2. I’m not a guru! Wednesday, November 10, 2010
  • 5. JavaScript isn’t this anymore Wednesday, November 10, 2010
  • 7. JavaScript is trendy! Technology Radar Wednesday, November 10, 2010
  • 8. JavaScript is trendy! Technology Radar Wednesday, November 10, 2010
  • 9. At the beginning... Wednesday, November 10, 2010
  • 10. Hacked by Brendan Eich in one week... Wednesday, November 10, 2010
  • 11. Former Mocha, renamed to JavaScript by Netscape Wednesday, November 10, 2010
  • 12. after a while... Wednesday, November 10, 2010
  • 16. Back to study! Wednesday, November 10, 2010
  • 17. Started a notebook... Wednesday, November 10, 2010
  • 18. Essential Scope Wednesday, November 10, 2010
  • 19. function sum(x, y){ // implied global result = x + y; return result; } {antipattern} Wednesday, November 10, 2010
  • 20. Global variables are evil! Wednesday, November 10, 2010
  • 22. Always declare variables with var function sum(x, y){ var result = x + y; return result; } {pattern} Wednesday, November 10, 2010
  • 23. function foo(){ var a = b = 0; //... } {antipattern} Wednesday, November 10, 2010
  • 24. b become global function foo(){ var a = (b = 0); //... } {antipattern} Wednesday, November 10, 2010
  • 25. don’t use assign chain in definition function foo(){ var a, b; a = b = 0; //... } {pattern} Wednesday, November 10, 2010
  • 26. Single var pattern function func(){ var a = 1, b = 2, sum = a + b, myobject = {}, i, j; // function body... } {pattern} Wednesday, November 10, 2010
  • 27. Don’t forget comma otherwise... Wednesday, November 10, 2010
  • 28. ... variables become globals Wednesday, November 10, 2010
  • 29. Hoisting myname = "global"; // global variable function func(){ // code... console.log(myname); // "undefined" // code... var myname = "local"; console.log(myname); // "local" } func(); {antipattern} Wednesday, November 10, 2010
  • 30. Hoisting myname = "global"; // global variable function func(){ var myname = "declared"; // code... console.log(myname); // "declared" // code... myname = "local"; console.log(myname); // "local" } func(); {pattern} Wednesday, November 10, 2010
  • 31. Against minimum vertical distance principle “Variables should be declared as close to their usage as possible” Robert C. Martin - Clean Code Wednesday, November 10, 2010
  • 32. Essential Literal and Constructor Wednesday, November 10, 2010
  • 33. In JavaScript almost everything is an object Wednesday, November 10, 2010
  • 34. It’s easy... var person = new Object(); person.name = "Scott"; person.say = function(){ return "I am " + this.name; }; console.log(person.say()); Wednesday, November 10, 2010
  • 35. but wrong! :-( var person = new Object(); person.name = "Scott"; person.say = function(){ return "I am " + this.name; }; console.log(person.say()); {antipattern} Wednesday, November 10, 2010
  • 36. var person = {}; person.name = "Scott"; person.say = function(){ return "I am " + this.name; }; console.log(person.say()); {pattern} Wednesday, November 10, 2010
  • 37. What if we need similar objects... var person = {}; person.name = "Scott"; person.say = function(){ return "I am " + this.name; }; console.log(person.say()); // I am Scott var otherPerson = {}; otherPerson.name = "Tiger"; otherPerson.say = function(){ return "I am " + this.name; }; console.log(otherPerson.say()); // I am Tiger Wednesday, November 10, 2010
  • 38. A lot of duplication var person = {}; person.name = "Scott"; person.say = function(){ return "I am " + this.name; }; console.log(person.say()); // I am Scott var otherPerson = {}; otherPerson.name = "Tiger"; otherPerson.say = function(){ return "I am " + this.name; }; console.log(otherPerson.say()); // I am Tiger Wednesday, November 10, 2010
  • 39. Duplication is evil! Wednesday, November 10, 2010
  • 40. Custom Constructor Functions var Person = function(name){ this.name = name; this.say = function(){ return "I am " + this.name; } } var person = new Person("Scott"); console.log(person.say()); // I am Scott {pattern} Wednesday, November 10, 2010
  • 41. Behind the scenes... var Person = function(name){ // var this = {}; this.name = name; this.say = function(){ return "I am " + this.name; }; // return this; }; {pattern} Wednesday, November 10, 2010
  • 42. So, at the end... var Person = function(name){ this.name = name; this.say = function(){ return "I am " + this.name; }; }; var scott = new Person('Scott'); var tiger = new Person('Tiger'); console.log(scott.say()); console.log(tiger.say()); {pattern} Wednesday, November 10, 2010
  • 43. What if we forget new? Wednesday, November 10, 2010
  • 44. this will point to global object var Person = function(name){ this.name = name; this.say = function(){ return "I am " + this.name; }; }; var scott = new Person('Scott') var adam = Person('Adam') console.log(typeof scott); //object console.log(scott.name); // Scott console.log(typeof adam); //'undefined' console.log(window.name); // Adam Wednesday, November 10, 2010
  • 45. Enforce new pattern one: naming convention Wednesday, November 10, 2010
  • 46. var Person = function(name){ var that = {}; that.name = name; that.say = function(){ return "I am " + that.name;}; return that; }; var scott = new Person('Scott') var adam = Person('Adam') console.log(typeof scott); //Object console.log(scott.name); // Scott console.log(typeof adam); //Object console.log(adam.name); // Adam {pattern} Wednesday, November 10, 2010
  • 47. Drawback: we loose prototype reference :-( var Person = function(name){ var that = {}; that.name = name; that.say = function(){ return "I am " + that.name; }; return that; }; Person.prototype.iamhumanbeing = true; var scott = new Person('Scott') var adam = Person('Adam') console.log(scott.iamhumanbeing); // undefined console.log(adam.iamhumanbeing); // undefined Wednesday, November 10, 2010
  • 48. Interm!zo Prototype property Wednesday, November 10, 2010
  • 49. Define ancestors chain var foo = {one: 1, two: 2}; var bar = {three: 3}; foo.__proto__ = bar; console.log(foo.one); console.log(foo.three); Wednesday, November 10, 2010
  • 50. bar three: 3 foo one: 1 two: 2 __proto__ Wednesday, November 10, 2010
  • 51. Behind the scenes... var Person = function(name){ // this.prototype = {constructor: this} var that = {}; that.name = name; that.say = function(){ return "I am " + that.name; }; return that; }; Wednesday, November 10, 2010
  • 52. Self invoking constructor var Person = function(name){ if (this instanceof Person) { this.name = name; this.say = function(){ return "I am " + that.name; } } else { return new Person(name); } }; Person.prototype.iamhumanbeing = true; var scott = new Person('Scott') var adam = Person('Adam') console.log(scott.name); // Scott console.log(adam.name); // Adam console.log(scott.iamhumanbeing); // true console.log(adam.iamhumanbeing); // true {pattern} Wednesday, November 10, 2010
  • 53. Essential Functions Wednesday, November 10, 2010
  • 54. Functions as first class objects Wednesday, November 10, 2010
  • 55. Immediate functions (function(){ alert('watch out!'); })(); Wednesday, November 10, 2010
  • 56. Initialization pattern (function(){ var days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], today = new Date(), msg = 'Today is ' + days[today.getDay()] + ', ' + today.getDate(); console.log(msg); })(); // "Today is Wed, 10" {pattern} Wednesday, November 10, 2010
  • 58. 5 globals... // constructors function Parent(){ } function Child(){ } // a variable var some_var = 1; // some objects var module1 = {}; module1.data = { a: 1, b: 2 }; var module2 = {}; {antipattern} Wednesday, November 10, 2010
  • 59. 1 global! // global object var MYAPP = (function(){ var my = {}; {pattern} // constructors my.Parent = function(){}; my.Child = function(){}; // a variable my.some_var = 1; // an object container my.modules = {}; // nested objects my.modules.module1 = {}; my.modules.module1.data = { a: 1, b: 2 }; my.modules.module2 = {}; return my; })(); console.log(MYAPP.modules.module1.data.a); // 1 Wednesday, November 10, 2010
  • 61. function Gadget(){ this.name = 'iPod'; this.stretch = function(){ return 'iPad'; } }; var toy = new Gadget(); console.log(toy.name); // `iPod` toy.name = 'Zune' console.log(toy.name); // `Zune` is public console.log(toy.stretch()); // stretch() is public {antipattern} Wednesday, November 10, 2010
  • 62. Create private member function Gadget(){ var name = 'iPod'; this.getName = function(){ return name; } }; var toy = new Gadget(); console.log(toy.getName()); // `iPod` toy.name = 'Zune' console.log(toy.getName()); // `iPod` {pattern} Wednesday, November 10, 2010
  • 63. for methods too function Gadget() { var name = 'iPod'; var upgrade = function(){ return 'iPhone'; } this.getName = function () { return name; } this.pay = function() { return upgrade(); } }; var toy = new Gadget(); console.log(toy.pay()); // `iPhone` console.log(toy.upgrade()); // `error` {pattern} Wednesday, November 10, 2010
  • 64. Advanced Code reuse patterns Wednesday, November 10, 2010
  • 65. Classical vs prototypal inheritance vs Wednesday, November 10, 2010
  • 66. Classical inheritance function Parent(name){ this.name = name; }; Parent.prototype.say = function(){ return 'My name is ' + this.name; }; function Child(name){ this.name = name; }; inherit(Child, Parent); var dad = new Parent('Larry'); var kid = new Child('Scott'); console.log(dad.say()); // 'My name is Larry' console.log(kid.say()); // 'My name is Scott' Wednesday, November 10, 2010
  • 67. function(){ return 'My name is ' + this.name; }; Parent.prototype say() new Parent() name: Larry __proto__ console.log(dad.say()); Wednesday, November 10, 2010
  • 68. Default Classical Inheritance pattern function inherit(C, P) { C.prototype = new P(); }; Wednesday, November 10, 2010
  • 69. function(){ return 'My name is ' + this.name; }; Parent.prototype say() new Parent() new Child() name: Larry name: Scott __proto__ __proto__ console.log(kid.say()); Wednesday, November 10, 2010
  • 70. Drawback: it doesn’t call parent constructor function Parent(name){ this.name = name; }; Parent.prototype.say = function(){ return 'My name is ' + this.name; }; function Child(name){ this.name = name; }; inherit(Child, Parent); var dad = new Parent('Larry'); var kid = new Child('Scott'); console.log(dad.say()); // 'My name is Larry' console.log(kid.say()); // 'My name is Scott' Wednesday, November 10, 2010
  • 71. Drawback: it doesn’t call parent constructor function Parent(name){ this.name = name; }; Parent.prototype.say = function(){ return 'My name is ' + this.name; }; function Child(name){ }; function inherit(C, P) { C.prototype = new P(); }; inherit(Child, Parent); var kid = new Child('Scott'); console.log(kid.say()); // 'My name is undefined' Wednesday, November 10, 2010
  • 72. Pattern Extension: rent a constructor function Child(name){ Parent.apply(this, arguments); }; Wednesday, November 10, 2010
  • 73. Pattern Extension: rent a constructor function Parent(name){ this.name = name; }; Parent.prototype.say = function(){ return 'My name is ' + this.name; }; function Child(name){ Parent.apply(this, arguments); }; function inherit(C, P){ C.prototype = new P(); }; inherit(Child, Parent); var dad = new Parent('Larry'); var kid = new Child('Scott'); console.log(dad.say()); // 'My name is Larry' console.log(kid.say()); // 'My name is Scott' Wednesday, November 10, 2010
  • 74. Drawback: parent constructor is called twice function Parent(name){ this.name = name; }; Parent.prototype.say = function(){ return 'My name is ' + this.name; }; function Child(name){ Parent.apply(this, arguments); }; function inherit(C, P){ C.prototype = new P(); }; inherit(Child, Parent); var dad = new Parent('Larry'); var kid = new Child('Scott'); console.log(dad.say()); // 'My name is Larry' console.log(kid.say()); // 'My name is Scott' Wednesday, November 10, 2010
  • 75. Drawback: parent constructor is called twice function Parent(name){ this.name = name; }; Parent.prototype.say = function(){ return 'My name is ' + this.name; }; function Child(name){ Parent.apply(this, arguments); }; function inherit(C, P){ C.prototype = new P(); }; inherit(Child, Parent); var dad = new Parent('Larry'); var kid = new Child('Scott'); console.log(dad.say()); // 'My name is Larry' console.log(kid.say()); // 'My name is Scott' Wednesday, November 10, 2010
  • 76. Drawback: parent constructor is called twice function Parent(name){ this.name = name; }; Parent.prototype.say = function(){ return 'My name is ' + this.name; }; function Child(name){ Parent.apply(this, arguments); }; function inherit(C, P){ C.prototype = new P(); }; inherit(Child, Parent); var dad = new Parent('Larry'); var kid = new Child('Scott'); console.log(dad.say()); // 'My name is Larry' console.log(kid.say()); // 'My name is Scott' Wednesday, November 10, 2010
  • 77. mmmm let’s try with the same prototype Wednesday, November 10, 2010
  • 78. Share the same prototype function inherit(C, P){ C.prototype = P.prototype; }; Wednesday, November 10, 2010
  • 79. Parent.prototype say() new Child() new Parent() name: Scott name: Larry __proto__ __proto__ Wednesday, November 10, 2010
  • 80. Share the same prototype Inheritance works as expected Constructor called only once Low memory footprint Wednesday, November 10, 2010
  • 81. Share the same prototype Child objects can affect other objects Wednesday, November 10, 2010
  • 82. Enhance the pattern: temporary constructor function inherit(C, P) { var F = function () {}; F.prototype = P.prototype; C.prototype = new F(); }; Wednesday, November 10, 2010
  • 83. Parent.prototype say() new Parent() new F() name: Larry __proto__ __proto__ new Child() name: Scott __proto__ Wednesday, November 10, 2010
  • 84. The Holy Grail Pattern of classical inheritance function inherit(C, P) { var F = function () {}; F.prototype = P.prototype; C.prototype = new F(); C.uber = P.prototype; C.prototype.constructor = C; }; Wednesday, November 10, 2010
  • 85. We got it! Wednesday, November 10, 2010
  • 86. What about Prototypal Inheritance? Wednesday, November 10, 2010
  • 87. No more classes, only objects Wednesday, November 10, 2010
  • 88. What we want in prototypal inheritance var parent = { name: "Larry", say: function(){ return "My name is " + this.name; } }; var child = object(parent); child.name = 'Scott' console.log(child.say()); // "Scott" Wednesday, November 10, 2010
  • 89. Prototypal inheritance function function object(o) { function F() {} F.prototype = o; return new F(); }; Wednesday, November 10, 2010
  • 90. parent name: Scott say() child = new F() name: Larry __proto__ Wednesday, November 10, 2010
  • 91. With constructor function var Parent = function(name){ this.name = name; this.say = function(){ return "My name is " + this.name; } }; var child = object(new Parent("Larry")); child.name = 'Scott' console.log(child.say()); // "Scott" Wednesday, November 10, 2010
  • 92. better classical or prototypal? Wednesday, November 10, 2010
  • 94. Goals of inheritance is reuse and reduce duplication Wednesday, November 10, 2010
  • 95. isA relationship... Liskov principle... difficult to tame inheritance... Wednesday, November 10, 2010
  • 96. A modern and better approach is to use Mix-In Wednesday, November 10, 2010
  • 97. A beahviour... var Serializer = function () {}; Serializer.prototype = { serialize: function () { var output = []; for (key in this) { // append this[key] to output // ... } return output.join(', '); } }; Wednesday, November 10, 2010
  • 98. another beahviour... var XmlBuilder = function () {}; XmlBuilder.prototype = { toXml: function () { var output = ''; for (key in this) { // append xml of this[key] to output // ... } return output; } }; Wednesday, November 10, 2010
  • 99. and an object... var Author = function (name, books) { this.name = name || ""; this.books = books || []; } Wednesday, November 10, 2010
  • 100. result! augment(Author, Serializer); augment(Author, XmlBuilder); var author = new Author('Umberto Eco', ['Il nome della rosa', 'Il Pendolo di Foucault']); var serializedString = author.serialize(); console.log(serializedString); // name: Umberto Eco, // books: Il nome della rosa, // Il Pendolo di Foucault var xmlString = author.toXml(); console.log(xmlString); //<name>Umberto Eco</name> // <book>Il nome della rosa</book> // <book>Il Pendolo di Focault</book> Wednesday, November 10, 2010
  • 101. The recipe function augment(receivingClass, givingClass) { for (methodName in givingClass.prototype) { if (!receivingClass.prototype[methodName]) { receivingClass.prototype[methodName] = givingClass.prototype[methodName]; } } } Wednesday, November 10, 2010
  • 102. Advanced Design Patterns Wednesday, November 10, 2010
  • 104. “A design pattern is a general reusable solution to a commonly occurring problem” Wednesday, November 10, 2010
  • 105. JavaScript is not J@#*! Wednesday, November 10, 2010
  • 106. Factory pattern creation of objects subclasses decide which class to instantiate Wednesday, November 10, 2010
  • 107. var BicycleFactory = { createBicycle: function(model){ var bicycle; switch (model) { case 'The Speedster': bicycle = new Speedster(); break; case 'The Lowrider': bicycle = new Lowrider(); break; case 'The Comfort Cruiser': default: bicycle = new ComfortCruiser(); } Interface.ensureImplements(bicycle, Bicycle); bicycle.assemble(); bicycle.wash(); return bicycle; } }; var californiaCruisers = new BicycleFactory(); var yourNewBike = californiaCruisers.createBicycle('The Speedster'); Wednesday, November 10, 2010
  • 108. A more concrete example... var XMLHttpFactory = function(){ this.createXMLHttp = function(){ if (typeof XMLHttpRequest !== "undefined") { return XMLHttpRequest(); } else if (typeof window.ActiveXObject !== "undefined") { return ActiveXObject("MSXML2.XMLHttp"); } else { alert("XHR Object not in production"); } } }; var xhr = new XMLHttpFactory().createXMLHttp(); Wednesday, November 10, 2010
  • 109. It seems lightly broken.... Wednesday, November 10, 2010
  • 110. var XMLHttpFactory = function(){ this.createXMLHttp = function(){ if (typeof XMLHttpRequest !== "undefined") { return XMLHttpRequest(); } else if (typeof window.ActiveXObject !== "undefined") { return ActiveXObject("MSXML2.XMLHttp"); } else { alert("XHR Object not in production"); } } }; var xhr = new XMLHttpFactory().createXMLHttp(); Wednesday, November 10, 2010
  • 111. Chain of Responsibility pattern Wednesday, November 10, 2010
  • 112. Extract condition and action.... var XhrStandard = function(){ this.canHandle = function(){ return typeof XMLHttpRequest !== "undefined"; } this.xhr = function(){ return XMLHttpRequest(); } }; Wednesday, November 10, 2010
  • 113. another condition and action.... var XhrIe = function(){ this.canHandle = function(){ return typeof ActiveXObject !== "undefined"; } this.xhr = function(){ return ActiveXObject("MSXML2.XMLHttp"); } }; Wednesday, November 10, 2010
  • 114. and last one condition and action.... var XhrError = function(){ this.canHandle = function(){ return true; } this.xhr = function(){ throw("XHR Object not in production"); } }; Wednesday, November 10, 2010
  • 115. and the engine! var XMLHttpFactory = function(){ //... ChainLinks... var creators = [new XhrStandard(), new XhrIe(), new XhrError()]; this.createXMLHttp = function(){ var creator; for(var i = 0; i < creators.length; ++i){ creator = creators[i]; if(creator.canHandle()) { return creator.xhr(); } } } }; var xhr = new XMLHttpFactory().createXMLHttp(); console.log(xhr); Wednesday, November 10, 2010
  • 116. Or following the book... Wednesday, November 10, 2010
  • 117. Refactored an action... var XhrStandard = function(){ this.canHandle = function(){ return typeof XMLHttpRequest !== "undefined"; } this.xhr = function(){ if (this.canHandle()) { return XMLHttpRequest(); } return this.successor.xhr(); } this.addSuccessor = function(successor){ this.successor = successor; return this.successor; } }; Wednesday, November 10, 2010
  • 118. other action... var XhrIe = function(){ this.canHandle = function(){ return typeof ActiveXObject !== "undefined"; } this.xhr = function(){ if (this.canHandle()) { return ActiveXObject("MSXML2.XMLHttp"); } return this.successor.xhr(); } this.addSuccessor = function(successor){ this.successor = successor; return this.successor; } }; Wednesday, November 10, 2010
  • 119. last action... var XhrError = function(){ this.canHandle = function(){ return true; } this.xhr = function(){ throw ("XHR Object not in production"); } this.addSuccessor = function(successor){ this.successor = successor; return this.successor; } }; Wednesday, November 10, 2010
  • 120. and the engine! var XMLHttpFactory = function(){ //... ChainLinks... var creator = (function(){ var head = new XhrIe(); head.addSuccessor(new XhrStandard()) .addSuccessor(new XhrError()); return head; })(); this.createXMLHttp = function(){ return creator.xhr(); } }; var xhr = new XMLHttpFactory().createXMLHttp(); console.log(xhr); Wednesday, November 10, 2010
  • 122. Same for all... var XhrIe = function(){ this.canHandle = function(){ return typeof ActiveXObject !== "undefined"; } this.xhr = function(){ if (this.canHandle()) { return ActiveXObject("MSXML2.XMLHttp"); } return this.successor.xhr(); } this.addSuccessor = function(successor){ this.successor = successor; return this.successor; } }; Wednesday, November 10, 2010
  • 123. Similar for all.. var XhrIe = function(){ this.canHandle = function(){ return typeof ActiveXObject !== "undefined"; } this.xhr = function(){ if (this.canHandle()) { return ActiveXObject("MSXML2.XMLHttp"); } return this.successor.xhr(); } this.addSuccessor = function(successor){ this.successor = successor; return this.successor; } }; Wednesday, November 10, 2010
  • 125. Template Method pattern ... and a little bit of Mix-In Wednesday, November 10, 2010
  • 126. Extracted same and similar behaviours.... var ChainLink = function() {}; ChainLink.prototype.exec = function(){ if(this.canHandle()) { return this.doIt(); } return this.successor.exec(); }; ChainLink.prototype.addSuccessor = function(successor){ this.successor = successor; return this.successor; } Wednesday, November 10, 2010
  • 127. Augment an action... var XhrStandard = augment(function(){ this.canHandle = function(){ return typeof XMLHttpRequest !== "undefined"; } this.doIt = function(){ return XMLHttpRequest(); }; }, ChainLink); Wednesday, November 10, 2010
  • 128. another action... var XhrIe = augment(function(){ this.canHandle = function(){ return typeof ActiveXObject !== "undefined"; } this.doIt = function(){ return this.doIt(); }; }, ChainLink); Wednesday, November 10, 2010
  • 129. and last one. var XhrError = augment(function(){ this.canHandle = function(){ return true; } this.doIt = function(){ throw("XHR Object not in production"); } },ChainLink); Wednesday, November 10, 2010
  • 130. and the engine is the same! var XMLHttpFactory = function(){ //... ChainLinks... var creator = (function(){ var head = new XhrIe(); head.addSuccessor(new XhrStandard()) .addSuccessor(new XhrError()); return head; })(); this.createXMLHttp = function(){ return creator.xhr(); } }; var xhr = new XMLHttpFactory().createXMLHttp(); console.log(xhr); Wednesday, November 10, 2010
  • 131. It’s just a beginning... Wednesday, November 10, 2010
  • 136. “Save it for a rainy day!” Wednesday, November 10, 2010
  • 137. Check your code with jslint.com Wednesday, November 10, 2010
  • 139. giordano.scalzo@cleancode.it @giordanoscalzo www.slideshare.net/giordano github.com/gscalzo Wednesday, November 10, 2010