Docstoc

JavaScript Patters

Document Sample
JavaScript Patters Powered By Docstoc
					        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

				
DOCUMENT INFO
Description: Great presentations from experts about various web technologies and programming languages.