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

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Java scriptpatterns

895

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
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
895
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
44
Comments
0
Likes
3
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

×