139
Giordano Scalzo JavaScript Patterns Wednesday, November 10, 2010

Java scriptpatterns

Embed Size (px)

DESCRIPTION

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.

Citation preview

Page 1: Java scriptpatterns

Giordano Scalzo

JavaScript Patterns

Wednesday, November 10, 2010

Page 2: Java scriptpatterns

I’m not a guru!

Wednesday, November 10, 2010

Page 3: Java scriptpatterns

I’m still learning

Wednesday, November 10, 2010

Page 4: Java scriptpatterns

Why?

Wednesday, November 10, 2010

Page 5: Java scriptpatterns

JavaScript isn’t this anymore

Wednesday, November 10, 2010

Page 6: Java scriptpatterns

JavaScript is everywhere!

Wednesday, November 10, 2010

Page 7: Java scriptpatterns

Technology Radar

JavaScript is trendy!

Wednesday, November 10, 2010

Page 8: Java scriptpatterns

Technology Radar

JavaScript is trendy!

Wednesday, November 10, 2010

Page 9: Java scriptpatterns

At the beginning...

Wednesday, November 10, 2010

Page 10: Java scriptpatterns

Hacked by Brendan Eich in one week...

Wednesday, November 10, 2010

Page 11: Java scriptpatterns

Former Mocha, renamed to JavaScript by Netscape

Wednesday, November 10, 2010

Page 12: Java scriptpatterns

after a while...

Wednesday, November 10, 2010

Page 13: Java scriptpatterns

and...

Wednesday, November 10, 2010

Page 14: Java scriptpatterns

:-(

Wednesday, November 10, 2010

Page 15: Java scriptpatterns

and so...

Wednesday, November 10, 2010

Page 16: Java scriptpatterns

Back to study!

Wednesday, November 10, 2010

Page 17: Java scriptpatterns

Started a notebook...

Wednesday, November 10, 2010

Page 18: Java scriptpatterns

Essential

Scope

Wednesday, November 10, 2010

Page 19: Java scriptpatterns

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

{antipattern}Wednesday, November 10, 2010

Page 20: Java scriptpatterns

Global variables are evil!

Wednesday, November 10, 2010

Page 21: Java scriptpatterns

Variables clash

Wednesday, November 10, 2010

Page 22: Java scriptpatterns

Always declare variables with var

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

{pattern}Wednesday, November 10, 2010

Page 23: Java scriptpatterns

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

{antipattern}Wednesday, November 10, 2010

Page 24: Java scriptpatterns

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

{antipattern}

b become global

Wednesday, November 10, 2010

Page 25: Java scriptpatterns

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

don’t use assign chain in definition

{pattern}Wednesday, November 10, 2010

Page 26: Java scriptpatterns

function func(){ var a = 1,

b = 2, sum = a + b, myobject = {}, i, j;

// function body...}

{pattern}

Single var pattern

Wednesday, November 10, 2010

Page 27: Java scriptpatterns

Don’t forget comma otherwise...

Wednesday, November 10, 2010

Page 28: Java scriptpatterns

... variables become globals

Wednesday, November 10, 2010

Page 29: Java scriptpatterns

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

Page 30: Java scriptpatterns

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

Page 31: Java scriptpatterns

“Variables should be declared as close to their usage as possible”

Robert C. Martin - Clean Code

Against minimum vertical distance principle

Wednesday, November 10, 2010

Page 32: Java scriptpatterns

EssentialLiteral and Constructor

Wednesday, November 10, 2010

Page 33: Java scriptpatterns

In JavaScript almost everything is an object

Wednesday, November 10, 2010

Page 34: Java scriptpatterns

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

console.log(person.say());

It’s easy...

Wednesday, November 10, 2010

Page 35: Java scriptpatterns

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

console.log(person.say());

{antipattern}

but wrong! :-(

Wednesday, November 10, 2010

Page 36: Java scriptpatterns

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

console.log(person.say());

{pattern}Wednesday, November 10, 2010

Page 37: Java scriptpatterns

What if we need similar objects...

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

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

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

Wednesday, November 10, 2010

Page 38: Java scriptpatterns

A lot of duplication

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

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

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

Wednesday, November 10, 2010

Page 39: Java scriptpatterns

Duplication is evil!

Wednesday, November 10, 2010

Page 40: Java scriptpatterns

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

Custom Constructor Functions

{pattern}Wednesday, November 10, 2010

Page 41: Java scriptpatterns

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

Page 42: Java scriptpatterns

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());

So, at the end...

{pattern}Wednesday, November 10, 2010

Page 43: Java scriptpatterns

What if we forget new?

Wednesday, November 10, 2010

Page 44: Java scriptpatterns

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); //objectconsole.log(scott.name); // Scottconsole.log(typeof adam); //'undefined'console.log(window.name); // Adam

this will point to global object

Wednesday, November 10, 2010

Page 45: Java scriptpatterns

Enforce new pattern one: naming convention

Wednesday, November 10, 2010

Page 46: Java scriptpatterns

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); //Objectconsole.log(scott.name); // Scott

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

{pattern}Wednesday, November 10, 2010

Page 47: Java scriptpatterns

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); // undefinedconsole.log(adam.iamhumanbeing); // undefined

Wednesday, November 10, 2010

Page 48: Java scriptpatterns

Interm!zoPrototype property

Wednesday, November 10, 2010

Page 49: Java scriptpatterns

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

Page 50: Java scriptpatterns

foo

one: 1

__proto__

bar

three: 3

two: 2

Wednesday, November 10, 2010

Page 51: Java scriptpatterns

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

Behind the scenes...

Wednesday, November 10, 2010

Page 52: Java scriptpatterns

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); // Scottconsole.log(adam.name); // Adamconsole.log(scott.iamhumanbeing); // trueconsole.log(adam.iamhumanbeing); // true

Self invoking constructor

{pattern}Wednesday, November 10, 2010

Page 53: Java scriptpatterns

EssentialFunctions

Wednesday, November 10, 2010

Page 54: Java scriptpatterns

Functions as first class objects

Wednesday, November 10, 2010

Page 55: Java scriptpatterns

Immediate functions

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

Wednesday, November 10, 2010

Page 56: Java scriptpatterns

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

Page 57: Java scriptpatterns

Function scope

Wednesday, November 10, 2010

Page 58: Java scriptpatterns

// constructors function Parent(){}

function Child(){}

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

{antipattern}

5 globals...

Wednesday, November 10, 2010

Page 59: Java scriptpatterns

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

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

{pattern}1 global!

Wednesday, November 10, 2010

Page 60: Java scriptpatterns

What about encapsulation?

Wednesday, November 10, 2010

Page 61: Java scriptpatterns

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

Page 62: Java scriptpatterns

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`

Create private member

{pattern}Wednesday, November 10, 2010

Page 63: Java scriptpatterns

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}

for methods too

Wednesday, November 10, 2010

Page 64: Java scriptpatterns

AdvancedCode reuse patterns

Wednesday, November 10, 2010

Page 65: Java scriptpatterns

vs

Classical vs prototypal inheritance

Wednesday, November 10, 2010

Page 66: Java scriptpatterns

Classical inheritancefunction Parent(name){ this.name = name;};

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

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

inherit(Child, Parent);

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

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

Wednesday, November 10, 2010

Page 67: Java scriptpatterns

new Parent()

name: Larry__proto__

Parent.prototypesay()

console.log(dad.say());

function(){ return 'My name is ' + this.name;};

Wednesday, November 10, 2010

Page 68: Java scriptpatterns

Default Classical Inheritance pattern

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

Wednesday, November 10, 2010

Page 69: Java scriptpatterns

new Parent()

name: Larry__proto__

Parent.prototypesay()

new Child()

name: Scott__proto__

console.log(kid.say());

function(){ return 'My name is ' + this.name;};

Wednesday, November 10, 2010

Page 70: Java scriptpatterns

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

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

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

inherit(Child, Parent);

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

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

Drawback: it doesn’t call parent constructor

Wednesday, November 10, 2010

Page 71: Java scriptpatterns

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

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

function Child(name){ };

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

inherit(Child, Parent);

var kid = new Child('Scott');

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

Drawback: it doesn’t call parent constructor

Wednesday, November 10, 2010

Page 72: Java scriptpatterns

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

Pattern Extension: rent a constructor

Wednesday, November 10, 2010

Page 73: Java scriptpatterns

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

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

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

Pattern Extension: rent a constructor

Wednesday, November 10, 2010

Page 74: Java scriptpatterns

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

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

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

Drawback: parent constructor is called twice

Wednesday, November 10, 2010

Page 75: Java scriptpatterns

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

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

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

Drawback: parent constructor is called twice

Wednesday, November 10, 2010

Page 76: Java scriptpatterns

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

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

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

Drawback: parent constructor is called twice

Wednesday, November 10, 2010

Page 77: Java scriptpatterns

mmmm let’s try with the same prototype

Wednesday, November 10, 2010

Page 78: Java scriptpatterns

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

Share the same prototype

Wednesday, November 10, 2010

Page 79: Java scriptpatterns

new Parent()

name: Larry__proto__

Parent.prototypesay()

new Child()

name: Scott__proto__

Wednesday, November 10, 2010

Page 80: Java scriptpatterns

Share the same prototype

Inheritance works as expectedConstructor called only onceLow memory footprint

Wednesday, November 10, 2010

Page 81: Java scriptpatterns

Share the same prototype

Child objects can affect other objects

Wednesday, November 10, 2010

Page 82: Java scriptpatterns

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

Enhance the pattern: temporary constructor

Wednesday, November 10, 2010

Page 83: Java scriptpatterns

new Parent()

name: Larry__proto__

Parent.prototypesay()

new Child()

name: Scott__proto__

new F()

__proto__

Wednesday, November 10, 2010

Page 84: Java scriptpatterns

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

The Holy Grail Pattern of classical inheritance

Wednesday, November 10, 2010

Page 85: Java scriptpatterns

We got it!

Wednesday, November 10, 2010

Page 86: Java scriptpatterns

What about Prototypal Inheritance?

Wednesday, November 10, 2010

Page 87: Java scriptpatterns

No more classes, only objects

Wednesday, November 10, 2010

Page 88: Java scriptpatterns

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

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

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

What we want in prototypal inheritance

Wednesday, November 10, 2010

Page 89: Java scriptpatterns

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

Prototypal inheritance function

Wednesday, November 10, 2010

Page 90: Java scriptpatterns

child = new F()

name: Larry__proto__

parent

name: Scottsay()

Wednesday, November 10, 2010

Page 91: Java scriptpatterns

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

Page 92: Java scriptpatterns

better classical or prototypal?

Wednesday, November 10, 2010

Page 93: Java scriptpatterns

It depends

Wednesday, November 10, 2010

Page 94: Java scriptpatterns

Goals of inheritance is reuse and reduce duplication

Wednesday, November 10, 2010

Page 95: Java scriptpatterns

isA relationship...Liskov principle...

difficult to tame inheritance...

Wednesday, November 10, 2010

Page 96: Java scriptpatterns

A modern and better approach is to use

Mix-In

Wednesday, November 10, 2010

Page 97: Java scriptpatterns

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

A beahviour...

Wednesday, November 10, 2010

Page 98: Java scriptpatterns

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

another beahviour...

Wednesday, November 10, 2010

Page 99: Java scriptpatterns

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

and an object...

Wednesday, November 10, 2010

Page 100: Java scriptpatterns

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 Foucaultvar xmlString = author.toXml();console.log(xmlString); //<name>Umberto Eco</name> // <book>Il nome della rosa</book> // <book>Il Pendolo di Focault</book>

result!

Wednesday, November 10, 2010

Page 101: Java scriptpatterns

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

givingClass.prototype[methodName]; } }}

The recipe

Wednesday, November 10, 2010

Page 102: Java scriptpatterns

AdvancedDesign Patterns

Wednesday, November 10, 2010

Page 103: Java scriptpatterns

Wednesday, November 10, 2010

Page 104: Java scriptpatterns

“A design pattern is a general reusable solution to a commonly occurring problem”

Wednesday, November 10, 2010

Page 105: Java scriptpatterns

JavaScript is not J@#*!

Wednesday, November 10, 2010

Page 106: Java scriptpatterns

creation of objectssubclasses decide which class to instantiate

Factory pattern

Wednesday, November 10, 2010

Page 107: Java scriptpatterns

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

Page 108: Java scriptpatterns

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();

A more concrete example...

Wednesday, November 10, 2010

Page 109: Java scriptpatterns

It seems lightly broken....

Wednesday, November 10, 2010

Page 110: Java scriptpatterns

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

Page 111: Java scriptpatterns

Chain of Responsibility pattern

Wednesday, November 10, 2010

Page 112: Java scriptpatterns

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

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

Extract condition and action....

Wednesday, November 10, 2010

Page 113: Java scriptpatterns

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

another condition and action....

Wednesday, November 10, 2010

Page 114: Java scriptpatterns

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

and last one condition and action....

Wednesday, November 10, 2010

Page 115: Java scriptpatterns

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);

and the engine!

Wednesday, November 10, 2010

Page 116: Java scriptpatterns

Or following the book...

Wednesday, November 10, 2010

Page 117: Java scriptpatterns

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; } };

Refactored an action...

Wednesday, November 10, 2010

Page 118: Java scriptpatterns

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; } };

other action...

Wednesday, November 10, 2010

Page 119: Java scriptpatterns

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; } };

last action...

Wednesday, November 10, 2010

Page 120: Java scriptpatterns

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);

and the engine!

Wednesday, November 10, 2010

Page 121: Java scriptpatterns

mmm duplication...

Wednesday, November 10, 2010

Page 122: Java scriptpatterns

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; } };

Same for all...

Wednesday, November 10, 2010

Page 123: Java scriptpatterns

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; } };

Similar for all..

Wednesday, November 10, 2010

Page 124: Java scriptpatterns

Template Method pattern

Wednesday, November 10, 2010

Page 125: Java scriptpatterns

... and a little bit of Mix-In

Template Method pattern

Wednesday, November 10, 2010

Page 126: Java scriptpatterns

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; }

Extracted same and similar behaviours....

Wednesday, November 10, 2010

Page 127: Java scriptpatterns

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

Augment an action...

Wednesday, November 10, 2010

Page 128: Java scriptpatterns

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

another action...

Wednesday, November 10, 2010

Page 129: Java scriptpatterns

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

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

and last one.

Wednesday, November 10, 2010

Page 130: Java scriptpatterns

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);

and the engine is the same!

Wednesday, November 10, 2010

Page 131: Java scriptpatterns

It’s just a beginning...

Wednesday, November 10, 2010

Page 132: Java scriptpatterns

peep codepeep code

Wednesday, November 10, 2010

Page 133: Java scriptpatterns

Study

Wednesday, November 10, 2010

Page 134: Java scriptpatterns

Wednesday, November 10, 2010

Page 135: Java scriptpatterns

Wednesday, November 10, 2010

Page 136: Java scriptpatterns

“Save it for a rainy day!”

Wednesday, November 10, 2010

Page 137: Java scriptpatterns

Check your code with jslint.com

Wednesday, November 10, 2010

Page 138: Java scriptpatterns

Wednesday, November 10, 2010

Page 139: Java scriptpatterns

@giordanoscalzo

www.slideshare.net/giordano

github.com/gscalzo

[email protected]

Wednesday, November 10, 2010