JavaScript Patterns    Giordano ScalzoWednesday, November 10, 2010
I’m not a guru!Wednesday, November 10, 2010
I’m still learningWednesday, November 10, 2010
Why?Wednesday, November 10, 2010
JavaScript isn’t this anymoreWednesday, November 10, 2010
JavaScript is everywhere!Wednesday, November 10, 2010
JavaScript is trendy!            Technology RadarWednesday, November 10, 2010
JavaScript is trendy!            Technology RadarWednesday, 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 NetscapeWednesday, 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                                  ScopeWednesday, November 10, 2010
function sum(x, y){                                   // implied global                                   result = x + y; ...
Global variables are evil!Wednesday, November 10, 2010
Variables clashWednesday, November 10, 2010
Always declare variables with var                                      function sum(x, y){                                ...
function foo(){                                   var a = b = 0;                                   //...                  ...
b become global                               function foo(){                                   var a = (b = 0);          ...
don’t use assign chain in definition                               function foo(){                                   var a,...
Single var pattern                                function func(){                                    var a = 1,          ...
Don’t forget comma otherwise...Wednesday, November 10, 2010
... variables become globalsWednesday, November 10, 2010
Hoisting                               myname = "global"; // global variable                               function func()...
Hoisting                               myname = "global"; // global variable                               function func()...
Against minimum vertical distance                               principle              “Variables should be declared as cl...
Essential                               Literal and ConstructorWednesday, November 10, 2010
In JavaScript almost everything is an objectWednesday, November 10, 2010
It’s easy...                               var person = new Object();                               person.name = "Scott";...
but wrong! :-(                               var person = new Object();                               person.name = "Scott...
var person = {};                               person.name = "Scott";                               person.say = function(...
What if we need similar objects...                          var person = {};                          person.name = "Scott...
A lot of duplication                          var person = {};                          person.name = "Scott";            ...
Duplication is evil!Wednesday, November 10, 2010
Custom Constructor Functions                               var Person = function(name){                                   ...
Behind the scenes...                               var Person = function(name){                                   // var t...
So, at the end...                               var Person = function(name){                                   this.name =...
What if we forget new?Wednesday, November 10, 2010
this will point to global object                           var Person = function(name){                               this...
Enforce new pattern one: naming conventionWednesday, November 10, 2010
var Person = function(name){                                   var that = {};                                   that.name ...
Drawback: we loose prototype reference :-(                          var Person = function(name){                          ...
Interm!zo                                Prototype propertyWednesday, November 10, 2010
Define ancestors chain                               var foo = {one: 1, two: 2};                               var bar = {t...
bar                                        three: 3                                foo                               one: ...
Behind the scenes...                          var Person = function(name){                              // this.prototype ...
Self invoking constructor                               var Person = function(name){                                   if ...
Essential                                  FunctionsWednesday, November 10, 2010
Functions as first class objectsWednesday, November 10, 2010
Immediate functions                                (function(){                                    alert(watch out!);     ...
Initialization pattern                               (function(){                                   var days = [Sun, Mon, ...
Function scopeWednesday, November 10, 2010
5 globals...                               // constructors                               function Parent(){               ...
1 global!                         // global object                         var MYAPP = (function(){                       ...
What about encapsulation?Wednesday, November 10, 2010
function Gadget(){                       this.name = iPod;                       this.stretch = function(){               ...
Create private member                               function Gadget(){                                   var name = iPod; ...
for methods too                               function Gadget() {                                   var name = iPod;      ...
Advanced                               Code reuse patternsWednesday, November 10, 2010
Classical vs prototypal inheritance                                             vsWednesday, November 10, 2010
Classical inheritance                               function Parent(name){                                   this.name = n...
function(){                                                  return My name is  + this.name;                              ...
Default Classical Inheritance pattern                                      function inherit(C, P) {                       ...
function(){                                           return My name is  + this.name;                                     ...
Drawback: it doesn’t call parent constructor                               function Parent(name){                         ...
Drawback: it doesn’t call parent constructor                     function Parent(name){                         this.name ...
Pattern Extension: rent a constructor                               function Child(name){                                 ...
Pattern Extension: rent a constructor                       function Parent(name){                           this.name = n...
Drawback: parent constructor is called twice                       function Parent(name){                           this.n...
Drawback: parent constructor is called twice                       function Parent(name){                           this.n...
Drawback: parent constructor is called twice                       function Parent(name){                           this.n...
mmmm let’s try with the same prototypeWednesday, November 10, 2010
Share the same prototype                               function inherit(C, P){                                   C.prototy...
Parent.prototype                                       say()                    new Child()                      new Paren...
Share the same prototype                               Inheritance works as expected                               Constru...
Share the same prototype                               Child objects can affect other objectsWednesday, November 10, 2010
Enhance the pattern: temporary constructor                               function inherit(C, P) {                         ...
Parent.prototype                                    say()            new Parent()                            new F()      ...
The Holy Grail Pattern of classical inheritance                               function inherit(C, P) {                    ...
We got it!Wednesday, November 10, 2010
What about Prototypal Inheritance?Wednesday, November 10, 2010
No more classes, only objectsWednesday, November 10, 2010
What we want in prototypal inheritance                               var parent = {                                   name...
Prototypal inheritance function                                      function object(o) {                                 ...
parent                               name: Scott                                  say()                                   ...
With constructor function                               var Parent = function(name){                                   thi...
better classical or prototypal?Wednesday, November 10, 2010
It dependsWednesday, November 10, 2010
Goals of inheritance is reuse and reduce duplicationWednesday, November 10, 2010
isA relationship...                        Liskov principle...                  difficult to tame inheritance...Wednesday, ...
A modern and better approach is to use                                   Mix-InWednesday, November 10, 2010
A beahviour...                               var Serializer = function () {};                               Serializer.pro...
another beahviour...                       var XmlBuilder = function () {};                       XmlBuilder.prototype = {...
and an object...                               var Author = function (name, books) {                                   thi...
result!       augment(Author, Serializer);       augment(Author, XmlBuilder);       var author = new Author(Umberto Eco,  ...
The recipe                  function augment(receivingClass, givingClass) {                      for (methodName in giving...
Advanced                               Design PatternsWednesday, November 10, 2010
Wednesday, November 10, 2010
“A design pattern is a                               general reusable solution to                               a commonly...
JavaScript is not J@#*!Wednesday, November 10, 2010
Factory pattern                  creation of objects                  subclasses decide which class to instantiateWednesda...
var BicycleFactory = {      createBicycle: function(model){          var bicycle;          switch (model) {              c...
A more concrete example...     var XMLHttpFactory = function(){         this.createXMLHttp = function(){             if (t...
It seems lightly broken....Wednesday, November 10, 2010
var XMLHttpFactory = function(){         this.createXMLHttp = function(){             if (typeof XMLHttpRequest !== "undef...
Chain of Responsibility patternWednesday, November 10, 2010
Extract condition and action....                       var XhrStandard = function(){                            this.canHa...
another condition and action....                         var XhrIe = function(){                             this.canHandl...
and last one condition and action....                               var XhrError = function(){                            ...
and the engine!                var XMLHttpFactory = function(){                    //... ChainLinks...                    ...
Or following the book...Wednesday, November 10, 2010
Refactored an action...                   var XhrStandard = function(){                       this.canHandle = function(){...
other action...                      var XhrIe = function(){                          this.canHandle = function(){        ...
last action...                         var XhrError = function(){                             this.canHandle = function(){...
and the engine!                   var XMLHttpFactory = function(){                     //... ChainLinks...                ...
mmm duplication...Wednesday, November 10, 2010
Same for all...                      var XhrIe = function(){                          this.canHandle = function(){        ...
Similar for all..                      var XhrIe = function(){                          this.canHandle = function(){      ...
Template Method patternWednesday, November 10, 2010
Template Method pattern                               ... and a little bit of Mix-InWednesday, November 10, 2010
Extracted same and similar behaviours....                var ChainLink = function() {};                ChainLink.prototype...
Augment an action...                       var XhrStandard = augment(function(){                           this.canHandle ...
another action...                 var XhrIe = augment(function(){                     this.canHandle = function(){        ...
and last one.                               var XhrError = augment(function(){                                   this.canH...
and the engine is the same!                   var XMLHttpFactory = function(){                     //... ChainLinks...    ...
It’s just a beginning...Wednesday, November 10, 2010
peep codeWednesday, November 10, 2010
StudyWednesday, 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.comWednesday, November 10, 2010
Wednesday, November 10, 2010
giordano.scalzo@cleancode.it                               @giordanoscalzo                               www.slideshare.ne...
Upcoming SlideShare
Loading in …5
×

Java scriptpatterns

1,223 views
1,142 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 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
1,223
On SlideShare
0
From Embeds
0
Number of Embeds
5
Actions
Shares
0
Downloads
45
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

Java scriptpatterns

  1. 1. JavaScript Patterns Giordano ScalzoWednesday, November 10, 2010
  2. 2. I’m not a guru!Wednesday, November 10, 2010
  3. 3. I’m still learningWednesday, November 10, 2010
  4. 4. Why?Wednesday, November 10, 2010
  5. 5. JavaScript isn’t this anymoreWednesday, November 10, 2010
  6. 6. JavaScript is everywhere!Wednesday, November 10, 2010
  7. 7. JavaScript is trendy! Technology RadarWednesday, November 10, 2010
  8. 8. JavaScript is trendy! Technology RadarWednesday, November 10, 2010
  9. 9. At the beginning...Wednesday, November 10, 2010
  10. 10. Hacked by Brendan Eich in one week...Wednesday, November 10, 2010
  11. 11. Former Mocha, renamed to JavaScript by NetscapeWednesday, November 10, 2010
  12. 12. after a while...Wednesday, November 10, 2010
  13. 13. and...Wednesday, November 10, 2010
  14. 14. :-(Wednesday, November 10, 2010
  15. 15. and so...Wednesday, November 10, 2010
  16. 16. Back to study!Wednesday, November 10, 2010
  17. 17. Started a notebook...Wednesday, November 10, 2010
  18. 18. Essential ScopeWednesday, November 10, 2010
  19. 19. function sum(x, y){ // implied global result = x + y; return result; }{antipattern}Wednesday, November 10, 2010
  20. 20. Global variables are evil!Wednesday, November 10, 2010
  21. 21. Variables clashWednesday, November 10, 2010
  22. 22. Always declare variables with var function sum(x, y){ var result = x + y; return result; }{pattern}Wednesday, November 10, 2010
  23. 23. function foo(){ var a = b = 0; //... }{antipattern}Wednesday, November 10, 2010
  24. 24. b become global function foo(){ var a = (b = 0); //... }{antipattern}Wednesday, November 10, 2010
  25. 25. don’t use assign chain in definition function foo(){ var a, b; a = b = 0; //... }{pattern}Wednesday, November 10, 2010
  26. 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. 27. Don’t forget comma otherwise...Wednesday, November 10, 2010
  28. 28. ... variables become globalsWednesday, November 10, 2010
  29. 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. 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. 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. 32. Essential Literal and ConstructorWednesday, November 10, 2010
  33. 33. In JavaScript almost everything is an objectWednesday, November 10, 2010
  34. 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. 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. 36. var person = {}; person.name = "Scott"; person.say = function(){ return "I am " + this.name; }; console.log(person.say());{pattern}Wednesday, November 10, 2010
  37. 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. 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. 39. Duplication is evil!Wednesday, November 10, 2010
  40. 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. 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. 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. 43. What if we forget new?Wednesday, November 10, 2010
  44. 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. 45. Enforce new pattern one: naming conventionWednesday, November 10, 2010
  46. 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. 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. 48. Interm!zo Prototype propertyWednesday, November 10, 2010
  49. 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. 50. bar three: 3 foo one: 1 two: 2 __proto__Wednesday, November 10, 2010
  51. 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. 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. 53. Essential FunctionsWednesday, November 10, 2010
  54. 54. Functions as first class objectsWednesday, November 10, 2010
  55. 55. Immediate functions (function(){ alert(watch out!); })();Wednesday, November 10, 2010
  56. 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. 57. Function scopeWednesday, November 10, 2010
  58. 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. 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. 60. What about encapsulation?Wednesday, November 10, 2010
  61. 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. 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. 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. 64. Advanced Code reuse patternsWednesday, November 10, 2010
  65. 65. Classical vs prototypal inheritance vsWednesday, November 10, 2010
  66. 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. 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. 68. Default Classical Inheritance pattern function inherit(C, P) { C.prototype = new P(); };Wednesday, November 10, 2010
  69. 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. 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. 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. 72. Pattern Extension: rent a constructor function Child(name){ Parent.apply(this, arguments); };Wednesday, November 10, 2010
  73. 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. 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. 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. 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. 77. mmmm let’s try with the same prototypeWednesday, November 10, 2010
  78. 78. Share the same prototype function inherit(C, P){ C.prototype = P.prototype; };Wednesday, November 10, 2010
  79. 79. Parent.prototype say() new Child() new Parent() name: Scott name: Larry __proto__ __proto__Wednesday, November 10, 2010
  80. 80. Share the same prototype Inheritance works as expected Constructor called only once Low memory footprintWednesday, November 10, 2010
  81. 81. Share the same prototype Child objects can affect other objectsWednesday, November 10, 2010
  82. 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. 83. Parent.prototype say() new Parent() new F() name: Larry __proto__ __proto__ new Child() name: Scott __proto__Wednesday, November 10, 2010
  84. 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. 85. We got it!Wednesday, November 10, 2010
  86. 86. What about Prototypal Inheritance?Wednesday, November 10, 2010
  87. 87. No more classes, only objectsWednesday, November 10, 2010
  88. 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. 89. Prototypal inheritance function function object(o) { function F() {} F.prototype = o; return new F(); };Wednesday, November 10, 2010
  90. 90. parent name: Scott say() child = new F() name: Larry __proto__Wednesday, November 10, 2010
  91. 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. 92. better classical or prototypal?Wednesday, November 10, 2010
  93. 93. It dependsWednesday, November 10, 2010
  94. 94. Goals of inheritance is reuse and reduce duplicationWednesday, November 10, 2010
  95. 95. isA relationship... Liskov principle... difficult to tame inheritance...Wednesday, November 10, 2010
  96. 96. A modern and better approach is to use Mix-InWednesday, November 10, 2010
  97. 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. 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. 99. and an object... var Author = function (name, books) { this.name = name || ""; this.books = books || []; }Wednesday, November 10, 2010
  100. 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. 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. 102. Advanced Design PatternsWednesday, November 10, 2010
  103. 103. Wednesday, November 10, 2010
  104. 104. “A design pattern is a general reusable solution to a commonly occurring problem”Wednesday, November 10, 2010
  105. 105. JavaScript is not J@#*!Wednesday, November 10, 2010
  106. 106. Factory pattern creation of objects subclasses decide which class to instantiateWednesday, November 10, 2010
  107. 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. 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. 109. It seems lightly broken....Wednesday, November 10, 2010
  110. 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. 111. Chain of Responsibility patternWednesday, November 10, 2010
  112. 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. 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. 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. 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. 116. Or following the book...Wednesday, November 10, 2010
  117. 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. 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. 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. 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. 121. mmm duplication...Wednesday, November 10, 2010
  122. 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. 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. 124. Template Method patternWednesday, November 10, 2010
  125. 125. Template Method pattern ... and a little bit of Mix-InWednesday, November 10, 2010
  126. 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. 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. 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. 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. 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. 131. It’s just a beginning...Wednesday, November 10, 2010
  132. 132. peep codeWednesday, November 10, 2010
  133. 133. StudyWednesday, November 10, 2010
  134. 134. Wednesday, November 10, 2010
  135. 135. Wednesday, November 10, 2010
  136. 136. “Save it for a rainy day!”Wednesday, November 10, 2010
  137. 137. Check your code with jslint.comWednesday, November 10, 2010
  138. 138. Wednesday, November 10, 2010
  139. 139. giordano.scalzo@cleancode.it @giordanoscalzo www.slideshare.net/giordano github.com/gscalzoWednesday, November 10, 2010

×