Your SlideShare is downloading. ×
Java scriptpatterns
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Introducing the official SlideShare app

Stunning, full-screen experience for iPhone and Android

Text the download link to your phone

Standard text messaging rates apply

Java scriptpatterns

916
views

Published on

Un design pattern è soluzione generale e riusabile ad un problema ricorrente; ma tutti i design patterns "classici" possono essere utilizzati in Javascript? Esistono design patterns tipici di …

Un design pattern è soluzione generale e riusabile ad un problema ricorrente; ma tutti i design patterns "classici" possono essere utilizzati in Javascript? Esistono design patterns tipici di Javascript? In questo talk vedremo quali design pattern classici si possono implementare in Javascript, e come, così come nuovi pattern possono sfruttare al massimo le caratteristiche del linguaggio.


0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
916
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
43
Comments
0
Likes
4
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. JavaScript Patterns Giordano ScalzoWednesday, November 10, 2010
  • 2. I’m not a guru!Wednesday, November 10, 2010
  • 3. I’m still learningWednesday, November 10, 2010
  • 4. Why?Wednesday, November 10, 2010
  • 5. JavaScript isn’t this anymoreWednesday, November 10, 2010
  • 6. JavaScript is everywhere!Wednesday, November 10, 2010
  • 7. JavaScript is trendy! Technology RadarWednesday, November 10, 2010
  • 8. JavaScript is trendy! Technology RadarWednesday, 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 NetscapeWednesday, November 10, 2010
  • 12. after a while...Wednesday, November 10, 2010
  • 13. and...Wednesday, November 10, 2010
  • 14. :-(Wednesday, November 10, 2010
  • 15. and so...Wednesday, November 10, 2010
  • 16. Back to study!Wednesday, November 10, 2010
  • 17. Started a notebook...Wednesday, November 10, 2010
  • 18. Essential ScopeWednesday, 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
  • 21. Variables clashWednesday, 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 globalsWednesday, 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 CodeWednesday, November 10, 2010
  • 32. Essential Literal and ConstructorWednesday, November 10, 2010
  • 33. In JavaScript almost everything is an objectWednesday, 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 TigerWednesday, 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 TigerWednesday, 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); // AdamWednesday, November 10, 2010
  • 45. Enforce new pattern one: naming conventionWednesday, 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); // undefinedWednesday, November 10, 2010
  • 48. Interm!zo Prototype propertyWednesday, 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 FunctionsWednesday, November 10, 2010
  • 54. Functions as first class objectsWednesday, 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
  • 57. Function scopeWednesday, 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); // 1Wednesday, November 10, 2010
  • 60. What about encapsulation?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 patternsWednesday, November 10, 2010
  • 65. Classical vs prototypal inheritance vsWednesday, 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 ScottWednesday, 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 ScottWednesday, 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 undefinedWednesday, 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 ScottWednesday, 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 ScottWednesday, 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 ScottWednesday, 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 ScottWednesday, November 10, 2010
  • 77. mmmm let’s try with the same prototypeWednesday, 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 footprintWednesday, November 10, 2010
  • 81. Share the same prototype Child objects can affect other objectsWednesday, 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 objectsWednesday, 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
  • 93. It dependsWednesday, November 10, 2010
  • 94. Goals of inheritance is reuse and reduce duplicationWednesday, 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-InWednesday, 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 PatternsWednesday, November 10, 2010
  • 103. 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 instantiateWednesday, 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 patternWednesday, 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
  • 121. mmm duplication...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
  • 124. Template Method patternWednesday, November 10, 2010
  • 125. Template Method pattern ... and a little bit of Mix-InWednesday, 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
  • 132. peep codeWednesday, November 10, 2010
  • 133. StudyWednesday, November 10, 2010
  • 134. Wednesday, November 10, 2010
  • 135. Wednesday, November 10, 2010
  • 136. “Save it for a rainy day!”Wednesday, November 10, 2010
  • 137. Check your code with jslint.comWednesday, November 10, 2010
  • 138. Wednesday, November 10, 2010
  • 139. giordano.scalzo@cleancode.it @giordanoscalzo www.slideshare.net/giordano github.com/gscalzoWednesday, November 10, 2010