Design Patterns

Created by Matthew Elphick / maael
Made with Reveal.js

Design Patterns

  • Observer
  • Singleton
  • Decorator
  • Template Method
  • Strategy
  • Adapter

Observer

What is an Observer Pattern?

An Observer is a type of Behavioral Design Pattern, meaning that it organises communication between objects.


How does an Observer organise communication?

Involved Parties

Subject

Observer(s)

The Subject is simply an object.
This Subject keeps a list of objects (Observers) that depend on it.
The Subject automatically informs these Observers of any changes.
It does this by broadcasting a notification to the Observers.
May include data relating to topic.
Subjects can have Observers added.
And they can be removed.

Comparing the
Observer Pattern & Pub/Sub

Pub/Sub is a variation of the Observer Pattern.

It has a channel to fire and receive events on.

This channel avoids dependencies between the involved parties.

Fits into JavaScript as it works well with Event Driven approaches.

Observer| JavaScript

Observer| JavaScript

Subject

function Subject() {
this.observers = [];
}
Subject.prototype.addObserver = function(obj) {
this.observers.push(obj);
};
Subject.prototype.removeObserver = function(obj) {
for(var i = 0; i < this.observers.length; i++) {
if(this.observers[i] === obj) {
this.observers.splice(i, 1);
}
}
};
Subject.prototype.notify = function(information) {
for(var i = 0; i < this.observers.length; i++) {
this.observers[i].update(information);
}
}

Observer| JavaScript

Observer

function Observers() {}
Observers.prototype.update = function(information) {
// Do something with the information
}

Implementation Notes

This differs from some other implementation approaches as it places the list in the Subject itself.

Some other approaches, such as the example in JavaScript Design Patterns by Addy Osmani, have the list of Observers as a separate object that the Subject then works with.

Observer| Uses

Event driven systems. Such as notifications.

Allows object communication without assumptions - objects are not tightly coupled.

Observer| Issues

May require Mediator if Observer wants to be notified only after several Subjects trigger notifications.

Hard to find bugs, and to track what is observing what. Usually only found at run-time.

Singleton

What is a Singleton Pattern?

A Singleton is a type of Creational Design Pattern, meaning that it focuses on object creation.


How does a Singleton affect object creation?

Normal Object

A normal object can be instantiated multiple times.

Singleton

A Singleton is different, it can only be instantiated once.

And that instantiation is globally accessible, providing a single point of access.

Main difference between a
Singleton & Static Classes

You can 'lazy load' Singletons, you can't with Static Classes.

Which means resources are free until they're actually used.

Singleton| JavaScript

Singleton| JavaScript

My Approach

var Singleton = function() {
if(Singleton.prototype._instance instanceof Singleton) {
return Singleton.prototype._instance;
} else {
Singleton.prototype._instance = this;
}
/* Rest of Class */
};

The _instance on the prototype stores the single instance.

On creation the object checks for a stored instance to use.

If it can't find one, it uses the current instance.


var Singleton = function() {
if(Singleton.prototype._instance instanceof Singleton) {
return Singleton.prototype._instance;
} else {
Singleton.prototype._instance = this;
}
/* Rest of Class */
/* Private Variable */
var name = "test";
/* Public functions */
this.getName = function() {
return name;
}
this.setName = function(newName) {
name = newName;
}
};
var a = new Singleton(), b = Singleton();

notify("Check they are the same", a == b);
notify("Check names", a.getName() == b.getName());
a.setName("new test"); // Change name
notify("Check names after change", a.getName() == b.getName());

Singleton| JavaScript

Alternative Approach

var Singleton = (function() {
var instance;
function init() {
// Private Methods and Variables
return {
// Public Methods and Variables
};
};
return {
getInstance: function() {
if(!instance) {
    instance = init();
}
return instance();
}
};
})();
This approach is from JavaScript Design Patterns by Addy Osmani

var Singleton = (function() {
var instance;
function init() {
// Private Methods and Variables
var name = "test";
return {
// Public Methods and Variables
getName: function() { return name; },
setName: function(newName) { name = newName; }
};
};
return {
getInstance: function() {
if(!instance) { instance = init(); }
return instance;
}
};
})();
var a = Singleton.getInstance(), b = Singleton.getInstance();

notify("Check they are the same", a == b);
notify("Check names", a.getName() == b.getName());
a.setName("new test"); // Change name
notify("Check names after change", a.getName() == b.getName());

Singleton| JavaScript

Approach Notes| My Approach
  • Requires at least the first created instance to be created using the new keyword.
  • The instance is accessible through the Singleton's prototype.

Singleton| JavaScript

Approach Notes| Alternative Approach
  • The Alternative Approach allows getInstance() to be altered, allowing subclassing.
  • The Alternative Approach uses the Module Pattern using closures via a self executing anonymous function to provide private scope that requires public exposure through the returned object.

Singleton| JavaScript

Really Simple Approach
var Singleton = ;

An object literal in JavaScript is a Singleton.

This form of Singleton has no constructor, and cannot be initialised.

Singleton| Uses

Namespace Code

Coordinate actions from a single object - for example a Database Connection Pool.

The commonly used Module Pattern is a manifestation of the Singleton Pattern.

Some people, such as Addy Osmani suggest that sometimes having to use Singletons in JavaScript specifically is a sign to re-evaluate the design of the code.

Singleton| Used By

Singleton| Issues

  • The Singleton Pattern relies on being globally accessible, meaning it must be added to the global namespace.
  • Difficult to test, as they can have difficulty creating multiple instances for different tests, or may hide dependencies among other things.
  • Can cause dependency issues due to tight coupling as anything using the Singleton relies on how the Singleton is created.
    As such it is prefered by some to use Dependency Injection over Singletons.

Q & A's

Comments or issues?

This presentation can be found on GitHub.

maael/design-patterns-presentation