KEMBAR78
Design patterns in javascript | PDF
Design Patterns in
Javascript
An introduction to Patterns developed by GoF.
Ayush Sharma
Agenda:
● Scalable apps and modules
● Why do we need patterns ?
● Patterns and Anti Patterns in JS
● And More Patterns …..
In the beginning empires, generally start out small.
Reference : :@addyosmani
With time, we add a few more ships to our fleet and it
begins to grow.
Soon enough, we have so many ships it becomes difficult
to handle communication and organisation.
What if all of this grinds to a halt because a ship goes
offline ? Can everything keep on functioning?
We can introduce a central way of controlling this chaos
and solving these problems e.g. the Death Star
If a ship goes down, the Death Star can respond and react
accordingly. e.g. Get rid of the old ship, send a
replacement.
Think about the future. You should be able to change
‘death stars’ if you and something better
What do we need ?
● Functionality broken down into smaller independent modules.
● Loosely coupled architecture.
● Framework or library agnostic. Flexibility to change in future.
● An intermediate layer interprets requests. Modules don’t access the
core or libraries directly.
● Prevent apps from falling over due to errors with specific modules.
Why do we need design patterns ?
● When creating or maintaining solutions, one of the most powerful
approaches to getting all developers or teams of your
organization on the same page is creating Design patterns.
● If working on a significantly large JavaScript app, remember to
dedicate sufficient time to planning the underlying architecture that
makes the most sense.
It’s often more complex than we initially think.
Tools we need:
● Design Patterns + Javascript = Scalable Architecture
● One of the most important aspects of writing
maintainable code is being able to notice the recurring
themes in that code and optimize them.
Origin of Patterns ?
● Early work of an architect Christopher Alexander.
● He produced a pattern language that would help empower
anyone wishing to design and build at any scale.
● In 1995, Erich, Richard, Ralph and John - a group that
became known as the Gang of Four (or GoF for short)
published Design Patterns: Elements Of Reusable
Object-Oriented Software
What is Design Pattern ?
● A reusable solution that can be applied to commonly
occurring problems in software design.
● They’re proven.
● They’re reusable.
● They’re expressive.
● They offer value.
Anti Pattern ?
● Describe a bad solution to a particular problem which
resulted in a bad situation occurring.
● Describe how to get out of said situation and how to go
from there to a good solution.
● Knowledge of anti-patterns is critical for success.
Anti Patterns in JS :
● Polluting the global namespace by defining a large
number of variables in the global context.
● Modifying the Object class prototype.
● Using JS as inline form.
● Use of document.write where native DOM alternatives
such as document.createElement are more appropriate.
Anti Patterns in JS :
● Improper Use of Truthy and Falsey Evaluation. Values of
zero (0), an empty string (""), null, undefined, and NaN are
all falsey in JavaScript.
● Many More...
Javascript Design Patterns
Writing code that’s expressive, encapsulated &
structured.
“Design patterns describe object-oriented designs,
they are based on practical solutions that have
been implemented in mainstream object-oriented
programming languages ....”
1. The Constructor Pattern
● Constructor is a special method used to initialize a newly
created object once memory has been allocated for it.
● In JavaScript, as almost everything is an object.
● Constructor can use to set the values of member
properties and methods when the object is first created.
1. The Constructor Pattern - Object Creation
var newObject = {};
// or
var newObject = Object.create( Object.prototype );
// or
var newObject = new Object();
1. The Constructor Pattern
You can set and get the properties using 3 ways:
● Dot notation
● Square Bracket
● Object.define
1. The Constructor Pattern - Object Assignment
You can set and get the properties of an object using 3 ways:
● Dot notation
// Set properties
newObject.someKey = "Hello World";
// Get properties
var value = newObject.someKey;
1. The Constructor Pattern - Object Assignment
You can set and get the properties of an object using 3 ways:
● Square Bracket
// Set properties
newObject["someKey"] = "Hello World";
// Get properties
var value = newObject["someKey"];
1. The Constructor Pattern - Object Assignment
You can set and get the properties of an object using 3 ways:
● Object.define
Object.defineProperty( newObject, "someKey", {
value: "for more control of the property's behavior",
writable: true,
enumerable: true,
configurable: true
});
1. The Constructor Pattern - Basic Constructor
● JavaScript doesn't support the concept of classes but it
does support special constructor functions that work
with objects.
● A call to a constructor function with the keyword "new",
the function behaves like a constructor.
● the keyword this references the new object that's being
created.
1. The Constructor Pattern - Basic Constructor
function Car( model, year, miles ) {
this.model = model;
this.year = year;
this.miles = miles;
this.toString = function () {
return this.model + " " + this.miles;
};
}
// We can create new instances of the car
var civic = new Car( "Honda Civic", 2009, 20000 );
console.log( civic.toString() );
1. The Constructor Pattern - Problem
You wanted a banana but what you got was a gorilla
holding the banana and the entire jungle.
● functions such as toString() are redefined for each of the
new objects created using the Car constructor.
● It makes inheritance difficult.
1. The Constructor Pattern - Prototypes
● Almost all objects in JavaScript, contain a "prototype"
object.
● When we call a JavaScript constructor to create an object,
all the properties of the constructor's prototype are then
made available to the new object.
1. The Constructor Pattern - Prototypes
function Car( model, year, miles ) {
this.model = model;
this.year = year;
this.miles = miles;
}
// Object.prototype.newMethod
Car.prototype.toString = function () {
return this.model + " has done " + this.miles + " miles";
};
var civic = new Car( "Honda Civic", 2009, 20000 );
console.log( civic.toString() );
2. The Module Pattern
● An interchangeable single-part of a larger system that
can be easily re-used.
● Modules are an integral piece of any robust application's
architecture and typically help in keeping the units of code
for a project both cleanly separated and organized.
2. The Module Pattern - IIFE
(function() {
// code to be immediately invoked
}()); // Crockford recommend this way
(function() {
// code to be immediately invoked
})(); // This is just as valid
This is great but there is no privacy in Javascript.
2. The Module Pattern - Privacy in Javascript
● No access modifiers.
● Variables and Methods can’t be public.
● Variables and Methods can’t be private.
● The Module pattern was originally defined as a way to
provide both private and public encapsulation for
classes in conventional software engineering.
2. The Module Pattern - Example
var myNamespace = (function () {
var myPrivateVar, myPrivateMethod;
myPrivateVar = 0;
myPrivateMethod = function( foo ) {
console.log( foo );
};
return {
myPublicVar: "foo",
myPublicFunction: function( bar ) {
myPrivateVar++;
myPrivateMethod( bar );
}
};
})();
● In the pattern, variables declared
are only available inside the
module.
● Variables defined within the
returning object are available to
everyone.
● This allows us to simulate privacy.
● It is the idea of true encapsulation,
at least from a JavaScript
perspective.
3. The Singleton Pattern
● It restricts instantiation of a class to a single object.
● Singleton pattern can be implemented by creating a class with
a method that creates a new instance of the class if one doesn't
exist. If instance already existing, it simply returns a reference
to that object.
● It serve as a shared resource namespace which separate
implementation code from the global namespace to provide a
single point of access for functions.
3. The Singleton Pattern
var mySingleton = (function () {
// Instance stores a reference to the Singleton
var instance;
function init() { // Singleton };
return {
// Get the Singleton instance if one exists
// or create one if it doesn't
getInstance: function () {
if ( !instance ) { // check for the instance
instance = init(); //
}
return instance;
}
};
})();
4. The Observer Pattern
4. The Observer Pattern
One or more observers are interested in the state of a subject
and register their interest with the subject by attaching
themselves. When something changes in our subject that the
observer may be interested in, a notify message is sent which
calls the update method in each observer. When the observer
is no longer interested in the subject's state, they can simply
detach themselves.
4. The Observer Pattern - Components
● Subject: maintains a list of observers, facilitates adding or removing
observers.
● Observer: provides an update interface for objects that need to be notified of
a Subject's changes of state.
● ConcreteSubject: broadcasts notifications to observers on changes of state.
● ConcreteObserver: stores a reference to the ConcreteSubject, implements
an update interface for the Observer to ensure state is consistent with the
Subject's
4. The Observer Pattern - Observer
// The Observer
function Observer(){
this.update = function(){
// ...
};
}
It has it’s update method.
4. The Observer Pattern - Observer List
function ObserverList(){
this.observerList = [];
}
ObserverList.prototype.add = function( obj ){
return this.observerList.push( obj );
};
ObserverList.prototype.count = function(){
return this.observerList.length;
};
ObserverList.prototype.get = function( index ){
if( index > -1 && index < this.observerList.length ){
return this.observerList[ index ];
}
};
4. The Observer Pattern - Observer List
ObserverList.prototype.indexOf = function( obj, startIndex ){
var i = startIndex;
while( i < this.observerList.length ){
if( this.observerList[i] === obj ){
return i;
}
i++;
}
return -1;
};
ObserverList.prototype.removeAt = function( index ){
this.observerList.splice( index, 1 );
};
4. The Observer Pattern - Subject
function Subject(){
this.observers = new ObserverList();
}
Subject.prototype.addObserver = function( observer ){
this.observers.add( observer );
};
Subject.prototype.removeObserver = function( observer ){
this.observers.removeAt( this.observers.indexOf( observer, 0 ) );
};
Subject.prototype.notify = function( context ){
var observerCount = this.observers.count();
for(var i=0; i < observerCount; i++){
this.observers.get(i).update( context );
}
};
5. The Mediator Pattern
● The dictionary refers to a mediator as a neutral party that assists in
negotiations and conflict resolution. In our world, a mediator is a
behavioral design pattern that allows us to expose a unified interface
through which the different parts of a system may communicate.
● The Mediator promotes loose coupling by ensuring that instead of
components referring to each other explicitly, their interaction is
handled through this central point.
5. The Mediator Pattern
● A real-world analogy could be a typical airport traffic
control system. A tower (Mediator) handles what planes
can take off and land because all communications
(notifications being listened out for or broadcast) are done
from the planes to the control tower, rather than from
plane-to-plane. A centralized controller is key to the
success of this system and that's really the role a Mediator
plays in software design.
5. The Mediator Pattern
● But … Perhaps the biggest downside of using the pattern
is that it can introduce a single point of failure. Placing a
Mediator between modules can also cause a
performance hit as they are always communicating
indirectly. Because of the nature of loose coupling, it's
difficult to establish how a system might react by only
looking at the broadcasts.
5. The Mediator Pattern
var orgChart = {
addNewEmployee: function(){
// getEmployeeDetail provides a view that users interact with
var employeeDetail = this.getEmployeeDetail();
// when the employee detail is complete, the mediator (the 'orgchart' object)
// decides what should happen next
employeeDetail.on("complete", function(employee){
// set up additional objects that have additional events, which are used
// by the mediator to do additional things
var managerSelector = this.selectManager(employee);
managerSelector.on("save", function(employee){
employee.save();
});
});
},
}
5. The Prototype Pattern
● It is based on prototypal inheritance where we create
objects which act as prototypes for other objects.
● It requires the use of Object.create.
● It is worth noting that prototypal relationships can cause
trouble when enumerating properties of objects and (as
Crockford recommends) wrapping the contents of the loop
in a hasOwnProperty() check.
5. The Prototype Pattern
● It is worth noting that prototypal relationships can cause
trouble when enumerating properties of objects and (as
Crockford recommends) wrapping the contents of the loop
in a hasOwnProperty() check..
● Object.create also allows us to easily implement
advanced concepts such as differential inheritance where
objects are able to directly inherit from other objects.
5. The Prototype Pattern
var myCar = {
name: "Ford Escort",
drive: function () {
console.log( "Weeee. I'm driving!" );
},
panic: function () {
console.log( "Wait. How do you stop this thing?" );
}
};
// Use Object.create to instantiate a new car
var yourCar = Object.create( myCar );
// Now we can see that one is a prototype of the other
console.log( yourCar.name );
6. The Command Pattern
● The Command pattern aims to encapsulate method invocation,
requests or operations into a single object and gives us the ability to
both parameterize and pass method calls around that can be
executed.
● The general idea behind the Command pattern is that it provides us a
means to separate the responsibilities of issuing commands from
anything executing commands, delegating this responsibility to
different objects instead.
6. The Command Pattern
(function(){
var carManager = {
// request information
requestInfo: function( model, id ){
return "The information for " + model + " with ID " + id + " is foobar";
},
// purchase the car
buyVehicle: function( model, id ){
return "You have successfully purchased Item " + id + ", a " + model;
},
// arrange a viewing
arrangeViewing: function( model, id ){
return "You have successfully booked a viewing of " + model + " ( " + id + " ) ";
}
};
})();
6. The Command Pattern
carManager.execute = function ( name ) {
return carManager[name] && carManager[name].apply( carManager,
[].slice.call(arguments, 1) );
};
carManager.execute( "buyVehicle", "Ford Escort", "453543" );
7. The Facade Pattern
● Convenient, high-level interfaces to larger bodies of code
that hide underlying complexity
● When you put up a facade, you're usually creating an
outward appearance which conceals a different reality.
Think of it as simplifying the API presented to other
developers
7. The Facade Pattern
var module = (function () {
var _private = {
i: 5,
get: function () {
console.log('current value:' + this.i);
},
set: function (val) {
this.i = val;
},
run: function () {
console.log('running');
},
jump: function () {
console.log('jumping');
}
};
return {
facade: function (args) {
// set values of private properties
_private.set(args.val);
// test setter
_private.get();
// optional: provide a simple interface
// to internal methods through the
// facade signature
if (args.run) {
_private.run();
}
}
}
}());
7. The Facade Pattern
● Simplifies usage through a limited, more readable API
● Hides the inner workings of a library. Allows
implementation to be less important.
● Differs from the module pattern as the exposed API can
greatly differ from the public/private methods defined.
8. The Mixin Pattern
● Mixins allow objects to borrow (or inherit) functionality
from them with a minimal amount of complexity.
● Mixins are classes which offer functionality that can be
easily inherited by a sub-class or group of sub-classes for
the purpose of function re-use.
8. The Mixin Pattern
var myMixins = {
moveUp: function(){
console.log( "move up" );
},
moveDown: function(){
console.log( "move down" );
},
stop: function(){
console.log( "stop! in the name of love!" );
}
};
8. The Mixin Pattern
// A skeleton carAnimator constructor
function CarAnimator(){
this.moveLeft = function(){
console.log( "move left" );
};
}
// A skeleton personAnimator constructor
function PersonAnimator(){
this.moveRandomly = function(){ /*..*/ };
}
// Extend both constructors with our Mixin
_.extend( CarAnimator.prototype, myMixins );
_.extend( PersonAnimator.prototype, myMixins );
More to see :
1. Factory pattern
2. Flyweight pattern
3. Decorator Pattern
Thanks !

Design patterns in javascript

  • 1.
    Design Patterns in Javascript Anintroduction to Patterns developed by GoF. Ayush Sharma
  • 2.
    Agenda: ● Scalable appsand modules ● Why do we need patterns ? ● Patterns and Anti Patterns in JS ● And More Patterns …..
  • 3.
    In the beginningempires, generally start out small. Reference : :@addyosmani
  • 4.
    With time, weadd a few more ships to our fleet and it begins to grow.
  • 5.
    Soon enough, wehave so many ships it becomes difficult to handle communication and organisation.
  • 6.
    What if allof this grinds to a halt because a ship goes offline ? Can everything keep on functioning?
  • 7.
    We can introducea central way of controlling this chaos and solving these problems e.g. the Death Star
  • 8.
    If a shipgoes down, the Death Star can respond and react accordingly. e.g. Get rid of the old ship, send a replacement.
  • 9.
    Think about thefuture. You should be able to change ‘death stars’ if you and something better
  • 10.
    What do weneed ? ● Functionality broken down into smaller independent modules. ● Loosely coupled architecture. ● Framework or library agnostic. Flexibility to change in future. ● An intermediate layer interprets requests. Modules don’t access the core or libraries directly. ● Prevent apps from falling over due to errors with specific modules.
  • 11.
    Why do weneed design patterns ? ● When creating or maintaining solutions, one of the most powerful approaches to getting all developers or teams of your organization on the same page is creating Design patterns. ● If working on a significantly large JavaScript app, remember to dedicate sufficient time to planning the underlying architecture that makes the most sense. It’s often more complex than we initially think.
  • 12.
    Tools we need: ●Design Patterns + Javascript = Scalable Architecture ● One of the most important aspects of writing maintainable code is being able to notice the recurring themes in that code and optimize them.
  • 13.
    Origin of Patterns? ● Early work of an architect Christopher Alexander. ● He produced a pattern language that would help empower anyone wishing to design and build at any scale. ● In 1995, Erich, Richard, Ralph and John - a group that became known as the Gang of Four (or GoF for short) published Design Patterns: Elements Of Reusable Object-Oriented Software
  • 14.
    What is DesignPattern ? ● A reusable solution that can be applied to commonly occurring problems in software design. ● They’re proven. ● They’re reusable. ● They’re expressive. ● They offer value.
  • 15.
    Anti Pattern ? ●Describe a bad solution to a particular problem which resulted in a bad situation occurring. ● Describe how to get out of said situation and how to go from there to a good solution. ● Knowledge of anti-patterns is critical for success.
  • 16.
    Anti Patterns inJS : ● Polluting the global namespace by defining a large number of variables in the global context. ● Modifying the Object class prototype. ● Using JS as inline form. ● Use of document.write where native DOM alternatives such as document.createElement are more appropriate.
  • 17.
    Anti Patterns inJS : ● Improper Use of Truthy and Falsey Evaluation. Values of zero (0), an empty string (""), null, undefined, and NaN are all falsey in JavaScript. ● Many More...
  • 18.
    Javascript Design Patterns Writingcode that’s expressive, encapsulated & structured. “Design patterns describe object-oriented designs, they are based on practical solutions that have been implemented in mainstream object-oriented programming languages ....”
  • 19.
    1. The ConstructorPattern ● Constructor is a special method used to initialize a newly created object once memory has been allocated for it. ● In JavaScript, as almost everything is an object. ● Constructor can use to set the values of member properties and methods when the object is first created.
  • 20.
    1. The ConstructorPattern - Object Creation var newObject = {}; // or var newObject = Object.create( Object.prototype ); // or var newObject = new Object();
  • 21.
    1. The ConstructorPattern You can set and get the properties using 3 ways: ● Dot notation ● Square Bracket ● Object.define
  • 22.
    1. The ConstructorPattern - Object Assignment You can set and get the properties of an object using 3 ways: ● Dot notation // Set properties newObject.someKey = "Hello World"; // Get properties var value = newObject.someKey;
  • 23.
    1. The ConstructorPattern - Object Assignment You can set and get the properties of an object using 3 ways: ● Square Bracket // Set properties newObject["someKey"] = "Hello World"; // Get properties var value = newObject["someKey"];
  • 24.
    1. The ConstructorPattern - Object Assignment You can set and get the properties of an object using 3 ways: ● Object.define Object.defineProperty( newObject, "someKey", { value: "for more control of the property's behavior", writable: true, enumerable: true, configurable: true });
  • 25.
    1. The ConstructorPattern - Basic Constructor ● JavaScript doesn't support the concept of classes but it does support special constructor functions that work with objects. ● A call to a constructor function with the keyword "new", the function behaves like a constructor. ● the keyword this references the new object that's being created.
  • 26.
    1. The ConstructorPattern - Basic Constructor function Car( model, year, miles ) { this.model = model; this.year = year; this.miles = miles; this.toString = function () { return this.model + " " + this.miles; }; } // We can create new instances of the car var civic = new Car( "Honda Civic", 2009, 20000 ); console.log( civic.toString() );
  • 27.
    1. The ConstructorPattern - Problem You wanted a banana but what you got was a gorilla holding the banana and the entire jungle. ● functions such as toString() are redefined for each of the new objects created using the Car constructor. ● It makes inheritance difficult.
  • 28.
    1. The ConstructorPattern - Prototypes ● Almost all objects in JavaScript, contain a "prototype" object. ● When we call a JavaScript constructor to create an object, all the properties of the constructor's prototype are then made available to the new object.
  • 29.
    1. The ConstructorPattern - Prototypes function Car( model, year, miles ) { this.model = model; this.year = year; this.miles = miles; } // Object.prototype.newMethod Car.prototype.toString = function () { return this.model + " has done " + this.miles + " miles"; }; var civic = new Car( "Honda Civic", 2009, 20000 ); console.log( civic.toString() );
  • 30.
    2. The ModulePattern ● An interchangeable single-part of a larger system that can be easily re-used. ● Modules are an integral piece of any robust application's architecture and typically help in keeping the units of code for a project both cleanly separated and organized.
  • 31.
    2. The ModulePattern - IIFE (function() { // code to be immediately invoked }()); // Crockford recommend this way (function() { // code to be immediately invoked })(); // This is just as valid This is great but there is no privacy in Javascript.
  • 32.
    2. The ModulePattern - Privacy in Javascript ● No access modifiers. ● Variables and Methods can’t be public. ● Variables and Methods can’t be private. ● The Module pattern was originally defined as a way to provide both private and public encapsulation for classes in conventional software engineering.
  • 33.
    2. The ModulePattern - Example var myNamespace = (function () { var myPrivateVar, myPrivateMethod; myPrivateVar = 0; myPrivateMethod = function( foo ) { console.log( foo ); }; return { myPublicVar: "foo", myPublicFunction: function( bar ) { myPrivateVar++; myPrivateMethod( bar ); } }; })(); ● In the pattern, variables declared are only available inside the module. ● Variables defined within the returning object are available to everyone. ● This allows us to simulate privacy. ● It is the idea of true encapsulation, at least from a JavaScript perspective.
  • 34.
    3. The SingletonPattern ● It restricts instantiation of a class to a single object. ● Singleton pattern can be implemented by creating a class with a method that creates a new instance of the class if one doesn't exist. If instance already existing, it simply returns a reference to that object. ● It serve as a shared resource namespace which separate implementation code from the global namespace to provide a single point of access for functions.
  • 35.
    3. The SingletonPattern var mySingleton = (function () { // Instance stores a reference to the Singleton var instance; function init() { // Singleton }; return { // Get the Singleton instance if one exists // or create one if it doesn't getInstance: function () { if ( !instance ) { // check for the instance instance = init(); // } return instance; } }; })();
  • 36.
  • 37.
    4. The ObserverPattern One or more observers are interested in the state of a subject and register their interest with the subject by attaching themselves. When something changes in our subject that the observer may be interested in, a notify message is sent which calls the update method in each observer. When the observer is no longer interested in the subject's state, they can simply detach themselves.
  • 38.
    4. The ObserverPattern - Components ● Subject: maintains a list of observers, facilitates adding or removing observers. ● Observer: provides an update interface for objects that need to be notified of a Subject's changes of state. ● ConcreteSubject: broadcasts notifications to observers on changes of state. ● ConcreteObserver: stores a reference to the ConcreteSubject, implements an update interface for the Observer to ensure state is consistent with the Subject's
  • 39.
    4. The ObserverPattern - Observer // The Observer function Observer(){ this.update = function(){ // ... }; } It has it’s update method.
  • 40.
    4. The ObserverPattern - Observer List function ObserverList(){ this.observerList = []; } ObserverList.prototype.add = function( obj ){ return this.observerList.push( obj ); }; ObserverList.prototype.count = function(){ return this.observerList.length; }; ObserverList.prototype.get = function( index ){ if( index > -1 && index < this.observerList.length ){ return this.observerList[ index ]; } };
  • 41.
    4. The ObserverPattern - Observer List ObserverList.prototype.indexOf = function( obj, startIndex ){ var i = startIndex; while( i < this.observerList.length ){ if( this.observerList[i] === obj ){ return i; } i++; } return -1; }; ObserverList.prototype.removeAt = function( index ){ this.observerList.splice( index, 1 ); };
  • 42.
    4. The ObserverPattern - Subject function Subject(){ this.observers = new ObserverList(); } Subject.prototype.addObserver = function( observer ){ this.observers.add( observer ); }; Subject.prototype.removeObserver = function( observer ){ this.observers.removeAt( this.observers.indexOf( observer, 0 ) ); }; Subject.prototype.notify = function( context ){ var observerCount = this.observers.count(); for(var i=0; i < observerCount; i++){ this.observers.get(i).update( context ); } };
  • 43.
    5. The MediatorPattern ● The dictionary refers to a mediator as a neutral party that assists in negotiations and conflict resolution. In our world, a mediator is a behavioral design pattern that allows us to expose a unified interface through which the different parts of a system may communicate. ● The Mediator promotes loose coupling by ensuring that instead of components referring to each other explicitly, their interaction is handled through this central point.
  • 44.
    5. The MediatorPattern ● A real-world analogy could be a typical airport traffic control system. A tower (Mediator) handles what planes can take off and land because all communications (notifications being listened out for or broadcast) are done from the planes to the control tower, rather than from plane-to-plane. A centralized controller is key to the success of this system and that's really the role a Mediator plays in software design.
  • 45.
    5. The MediatorPattern ● But … Perhaps the biggest downside of using the pattern is that it can introduce a single point of failure. Placing a Mediator between modules can also cause a performance hit as they are always communicating indirectly. Because of the nature of loose coupling, it's difficult to establish how a system might react by only looking at the broadcasts.
  • 46.
    5. The MediatorPattern var orgChart = { addNewEmployee: function(){ // getEmployeeDetail provides a view that users interact with var employeeDetail = this.getEmployeeDetail(); // when the employee detail is complete, the mediator (the 'orgchart' object) // decides what should happen next employeeDetail.on("complete", function(employee){ // set up additional objects that have additional events, which are used // by the mediator to do additional things var managerSelector = this.selectManager(employee); managerSelector.on("save", function(employee){ employee.save(); }); }); }, }
  • 47.
    5. The PrototypePattern ● It is based on prototypal inheritance where we create objects which act as prototypes for other objects. ● It requires the use of Object.create. ● It is worth noting that prototypal relationships can cause trouble when enumerating properties of objects and (as Crockford recommends) wrapping the contents of the loop in a hasOwnProperty() check.
  • 48.
    5. The PrototypePattern ● It is worth noting that prototypal relationships can cause trouble when enumerating properties of objects and (as Crockford recommends) wrapping the contents of the loop in a hasOwnProperty() check.. ● Object.create also allows us to easily implement advanced concepts such as differential inheritance where objects are able to directly inherit from other objects.
  • 49.
    5. The PrototypePattern var myCar = { name: "Ford Escort", drive: function () { console.log( "Weeee. I'm driving!" ); }, panic: function () { console.log( "Wait. How do you stop this thing?" ); } }; // Use Object.create to instantiate a new car var yourCar = Object.create( myCar ); // Now we can see that one is a prototype of the other console.log( yourCar.name );
  • 50.
    6. The CommandPattern ● The Command pattern aims to encapsulate method invocation, requests or operations into a single object and gives us the ability to both parameterize and pass method calls around that can be executed. ● The general idea behind the Command pattern is that it provides us a means to separate the responsibilities of issuing commands from anything executing commands, delegating this responsibility to different objects instead.
  • 51.
    6. The CommandPattern (function(){ var carManager = { // request information requestInfo: function( model, id ){ return "The information for " + model + " with ID " + id + " is foobar"; }, // purchase the car buyVehicle: function( model, id ){ return "You have successfully purchased Item " + id + ", a " + model; }, // arrange a viewing arrangeViewing: function( model, id ){ return "You have successfully booked a viewing of " + model + " ( " + id + " ) "; } }; })();
  • 52.
    6. The CommandPattern carManager.execute = function ( name ) { return carManager[name] && carManager[name].apply( carManager, [].slice.call(arguments, 1) ); }; carManager.execute( "buyVehicle", "Ford Escort", "453543" );
  • 53.
    7. The FacadePattern ● Convenient, high-level interfaces to larger bodies of code that hide underlying complexity ● When you put up a facade, you're usually creating an outward appearance which conceals a different reality. Think of it as simplifying the API presented to other developers
  • 54.
    7. The FacadePattern var module = (function () { var _private = { i: 5, get: function () { console.log('current value:' + this.i); }, set: function (val) { this.i = val; }, run: function () { console.log('running'); }, jump: function () { console.log('jumping'); } }; return { facade: function (args) { // set values of private properties _private.set(args.val); // test setter _private.get(); // optional: provide a simple interface // to internal methods through the // facade signature if (args.run) { _private.run(); } } } }());
  • 55.
    7. The FacadePattern ● Simplifies usage through a limited, more readable API ● Hides the inner workings of a library. Allows implementation to be less important. ● Differs from the module pattern as the exposed API can greatly differ from the public/private methods defined.
  • 56.
    8. The MixinPattern ● Mixins allow objects to borrow (or inherit) functionality from them with a minimal amount of complexity. ● Mixins are classes which offer functionality that can be easily inherited by a sub-class or group of sub-classes for the purpose of function re-use.
  • 57.
    8. The MixinPattern var myMixins = { moveUp: function(){ console.log( "move up" ); }, moveDown: function(){ console.log( "move down" ); }, stop: function(){ console.log( "stop! in the name of love!" ); } };
  • 58.
    8. The MixinPattern // A skeleton carAnimator constructor function CarAnimator(){ this.moveLeft = function(){ console.log( "move left" ); }; } // A skeleton personAnimator constructor function PersonAnimator(){ this.moveRandomly = function(){ /*..*/ }; } // Extend both constructors with our Mixin _.extend( CarAnimator.prototype, myMixins ); _.extend( PersonAnimator.prototype, myMixins );
  • 59.
    More to see: 1. Factory pattern 2. Flyweight pattern 3. Decorator Pattern
  • 60.