Coding and Design Patterns - Object-Oriented JavaScript Second Edition (2013)

Object-Oriented JavaScript Second Edition (2013)

Chapter 8. Coding and Design Patterns

Now that you know all about the objects in JavaScript, you've mastered prototypes and inheritance, and you have seen some practical examples of using browser-specific objects, let's move forward, or rather move a level up. Let's have a look at some common JavaScript patterns.

But first, what's pattern? In short, a pattern is a good solution to a common problem.

Sometimes when you're facing a new programming problem, you may recognize right away that you've previously solved another, suspiciously similar problem. In such cases, it's worth isolating this class of problems and searching for a common solution. A pattern is a proven and reusable solution (or an approach to a solution) to a class of problems.

There are cases where a pattern is nothing more than an idea or a name. Sometimes just using a name helps you think more clearly about a problem. Also, when working with other developers in a team, it's much easier to communicate when everybody uses the same terminology to discuss a problem or a solution.

Other times you may come across a unique problem that doesn't look like anything you've seen before and doesn't readily fit into a known pattern. Blindly applying a pattern just for the sake of using a pattern is not a good idea. It's preferable to not use any known pattern than to try to tweak your problem so that it fits an existing solution.

This chapter talks about two types of patterns:

· Coding patterns: These are mostly JavaScript-specific best practices

· Design patterns: These are language-independent patterns, popularized by the famous "Gang of Four" book

Coding patterns

Let's start with some patterns that reflect JavaScript's unique features. Some patterns aim to help you organize your code (for example, namespacing), others are related to improving performance (such as lazy definitions and init-time branching), and some make up for missing features such as private properties. The patterns discussed in this section include:

· Separating behavior

· Namespaces

· Init-time branching

· Lazy definition

· Configuration objects

· Private variables and methods

· Privileged methods

· Private functions as public methods

· Immediate functions

· Chaining

· JSON

Separating behavior

As discussed previously, the three building blocks of a web page are as follows:

· Content (HTML)

· Presentation (CSS)

· Behavior (JavaScript)

Content

HTML is the content of the web page, the actual text. Ideally, the content should be marked up using the least amount of HTML tags that sufficiently describe the semantic meaning of that content. For example, if you're working on a navigation menu it's a good idea to use <ul> and <li> since a navigation menu is in essence just a list of links.

Your content (HTML) should be free from any formatting elements. Visual formatting belongs to the presentation layer and should be achieved through the use of Cascading Style Sheets (CSS). This means the following:

· The style attribute of HTML tags should not be used, if possible.

· Presentational HTML tags such as <font> should not be used at all.

· Tags should be used for their semantic meaning, not because of how browsers render them by default. For instance, developers sometimes use a <div> tag where a <p> would be more appropriate. It's also favorable to use <strong> and <em> instead of <b> and<i> as the latter describe the visual presentation rather than the meaning.

Presentation

A good approach to keep presentation out of the content is to reset, or nullify all browser defaults. For example, using reset.css from the Yahoo! UI library. This way the browser's default rendering won't distract you from consciously thinking about the proper semantic tags to use.

Behavior

The third component of a web page is the behavior. Behavior should be kept separate from both the content and the presentation. Behavior is usually added by using JavaScript that is isolated to <script> tags, and preferably contained in external files. This means not using any inline attributes such as onclick, onmouseover, and so on. Instead, you can use the addEventListener/attachEvent methods from the previous chapter.

The best strategy for separating behavior from content is as follows:

· Minimize the number of <script> tags

· Avoid inline event handlers

· Do not use CSS expressions

· Dynamically add markup that has no purpose if JavaScript is disabled by the user

· Towards the end of your content when you are ready to close the <body> tag, insert a single external.js file

Example of separating behavior

Let's say you have a search form on a page and you want to validate the form with JavaScript. So, you go ahead and keep the form tags free from any JavaScript, and then immediately before the closing the </body> tag you insert a <script> tag which links to an external file as follows:

<body>

<form id="myform" method="post" action="server.php">

<fieldset>

<legend>Search</legend>

<inputname="search"id="search"type="text"/>

<input type="submit" />

</fieldset>

</form>

<script src="behaviors.js"></script>

</body>

In behaviors.js you attach an event listener to the submit event. In your listener, you check to see if the text input field was left blank and if so, stop the form from being submitted. This way you save a round trip between the server and the client and make the application immediately responsive.

The content of behaviors.js is given in the following code. It assumes that you've created your myevent utility from the exercise at the end of the previous chapter:

// init

myevent.addListener('myform', 'submit', function (e) {

// no need to propagate further

e = myevent.getEvent(e);

myevent.stopPropagation(e);

// validate

var el = document.getElementById('search');

if (!el.value) { // too bad, field is empty

myevent.preventDefault(e); // prevent the form submission

alert('Please enter a search string');

}

});

Asynchronous JavaScript loading

You noticed how the script was loaded at the end of the HTML right before closing the body. The reason is that JavaScript blocks the DOM construction of the page and in some browsers even the downloads of the other components that follow. By moving the scripts to the bottom of the page you ensure the script is out of the way and when it arrives, it simply enhances the already usable page.

Another way to prevent external JavaScript files from blocking the page is to load them asynchronously. This way you can start loading them earlier. HTML5 has the defer attribute for this purpose:

<script defer src="behaviors.js"></script>

Unfortunately, the defer attribute is not supported by older browsers, but luckily, there is a solution that works across browsers, old and new. The solution is to create a script node dynamically and append it to the DOM. In other words you use a bit of inline JavaScript to load the external JavaScript file. You can have this script loader snippet at the top of your document so that the download has an early start:

...

<head>

(function () {

var s = document.createElement('script');

s.src = 'behaviors.js';

document.getElementsByTagName('head')[0].appendChild(s);

}());

</head>

...

Namespaces

Global variables should be avoided in order to reduce the possibility of variable naming collisions. You can minimize the number of globals by namespacing your variables and functions. The idea is simple, you create only one global object and all your other variables and functions become properties of that object.

An Object as a namespace

Let's create a global object called MYAPP:

// global namespace

var MYAPP = MYAPP || {};

Now, instead of having a global myevent utility (from the previous chapter), you can have it as an event property of the MYAPP object as follows:

// sub-object

MYAPP.event = {};

Adding the methods to the event utility is still the same:

// object together with the method declarations

MYAPP.event = {

addListener: function (el, type, fn) {

// .. do the thing

},

removeListener: function (el, type, fn) {

// ...

},

getEvent: function (e) {

// ...

}

// ... other methods or properties

};

Namespaced constructors

Using a namespace doesn't prevent you from creating constructor functions. Here is how you can have a DOM utility that has an Element constructor, which allows you to create DOM elements easier:

MYAPP.dom = {};

MYAPP.dom.Element = function (type, properties) {

var tmp = document.createElement(type);

for (var i in properties) {

if (properties.hasOwnProperty(i)) {

tmp.setAttribute(i, properties[i]);

}

}

return tmp;

};

Similarly, you can have a Text constructor to create text nodes:

MYAPP.dom.Text = function (txt) {

return document.createTextNode(txt);

};

Using the constructors to create a link at the bottom of a page can be done as follows:

var link = new MYAPP.dom.Element('a',

{href: 'http://phpied.com', target: '_blank'});

var text = new MYAPP.dom.Text('click me');

link.appendChild(text);

document.body.appendChild(link);

A namespace() method

You can create a namespace utility that makes your life easier so that you can use more convenient syntax:

MYAPP.namespace('dom.style');

Instead of the more verbose syntax as follows:

MYAPP.dom = {};

MYAPP.dom.style = {};

Here's how you can create such a namespace() method. First, you create an array by splitting the input string using the period (.) as a separator. Then, for every element in the new array, you add a property to your global object, if one doesn't already exist as follows:

var MYAPP = {};

MYAPP.namespace = function (name) {

var parts = name.split('.');

var current = MYAPP;

for (var i = 0; i < parts.length; i++) {

if (!current[parts[i]]) {

current[parts[i]] = {};

}

current = current[parts[i]];

}

};

Testing the new method is done as follows:

MYAPP.namespace('event');

MYAPP.namespace('dom.style');

The result of the preceding code is the same as if you did the following:

var MYAPP = {

event: {},

dom: {

style: {}

}

};

Init-time branching

In the previous chapter you noticed that sometimes different browsers have different implementations for the same or similar functionalities. In such cases, you need to branch your code depending on what's supported by the browser currently executing your script. Depending on your program this branching can happen far too often and, as a result, may slow down the script execution.

You can mitigate this problem by branching some parts of the code during initialization, when the script loads, rather than during runtime. Building upon the ability to define functions dynamically, you can branch and define the same function with a different body depending on the browser. Let's see how.

First, let's define a namespace and placeholder method for the event utility:

var MYAPP = {};

MYAPP.event = {

addListener: null,

removeListener: null

};

At this point, the methods to add or remove a listener are not implemented. Based on the results from feature sniffing, these methods can be defined differently as follows:

if (window.addEventListener) {

MYAPP.event.addListener = function (el, type, fn) {

el.addEventListener(type, fn, false);

};

MYAPP.event.removeListener = function (el, type, fn) {

el.removeEventListener(type, fn, false);

};

} else if (document.attachEvent) { // IE

MYAPP.event.addListener = function (el, type, fn) {

el.attachEvent('on' + type, fn);

};

MYAPP.event.removeListener = function (el, type, fn) {

el.detachEvent('on' + type, fn);

};

} else { // older browsers

MYAPP.event.addListener = function (el, type, fn) {

el['on' + type] = fn;

};

MYAPP.event.removeListener = function (el, type) {

el['on' + type] = null;

};

}

After this script executes, you have the addListener() and removeListener() methods defined in a browser-dependent way. Now, every time you invoke one of these methods there's no more feature-sniffing and it results in less work and faster execution.

One thing to watch out for when sniffing features is not to assume too much after checking for one feature. In the previous example this rule is broken because the code only checks for addEventListener support but then defines both addListener() andremoveListener(). In this case it's probably safe to assume that if a browser implements addEventListener() it also implements removeEventListener(). But, imagine what happens if a browser implements stopPropagation() but not preventDefault() and you haven't checked for these individually. You have assumed that because addEventListener() is not defined, the browser must be an old IE and write your code using your knowledge and assumptions of how IE works. Remember that all of your knowledge is based on the way a certain browser works today, but not necessarily the way it will work tomorrow. So to avoid many rewrites of your code as new browser versions are shipped, it's best to individually check for features you intend to use and don't generalize on what a certain browser supports.

Lazy definition

The lazy definition pattern is similar to the previous init-time branching pattern. The difference is that the branching happens only when the function is called for the first time. When the function is called, it redefines itself with the best implementation. Unlike the init-time branching where the if happens once, during loading, here it may not happen at all in cases when the function is never called. The lazy definition also makes the initialization process lighter as there's no init-time branching work to be done.

Let's see an example that illustrates this via the definition of an addListener() function. The function is first defined with a generic body. It checks which functionality is supported by the browser when it's called for the first time and then redefines itself using the most suitable implementation. At the end of the first call, the function calls itself so that the actual event attaching is performed. The next time you call the same function it will be defined with its new body and be ready for use, so no further branching is necessary. Following is the code snippet:

var MYAPP = {};

MYAPP.myevent = {

addListener: function (el, type, fn) {

if (el.addEventListener) {

MYAPP.myevent.addListener = function (el, type, fn) {

el.addEventListener(type, fn, false);

};

} else if (el.attachEvent) {

MYAPP.myevent.addListener = function (el, type, fn) {

el.attachEvent('on' + type, fn);

};

} else {

MYAPP.myevent.addListener = function (el, type, fn) {

el['on' + type] = fn;

};

}

MYAPP.myevent.addListener(el, type, fn);

}

};

Configuration object

This pattern is convenient when you have a function or method that accepts a lot of optional parameters. It's up to you to decide how many constitutes a lot. But generally, a function with more than three parameters is not convenient to call because you have to remember the order of the parameters, and it is even more inconvenient when some of the parameters are optional.

Instead of having many parameters, you can use one parameter and make it an object. The properties of the object are the actual parameters. This is suitable for passing configuration options because these tend to be numerous and optional (with smart defaults). The beauty of using a single object as opposed to multiple parameters is described as follows:

· The order doesn't matter

· You can easily skip parameters that you don't want to set

· It's easy to add more optional configuration attributes

· It makes the code more readable because the configuration object's properties are present in the calling code along with their names

Imagine you have some sort of UI widget constructor you use to create fancy buttons. It accepts the text to put inside the button (the value attribute of the <input> tag) and an optional parameter of the type of button. For simplicity let's say the fancy button takes the same configuration as a regular button. Have a look at the following code:

// a constructor that creates buttons

MYAPP.dom.FancyButton = function (text, type) {

var b = document.createElement('input');

b.type = type || 'submit';

b.value = text;

return b;

};

Using the constructor is simple; you just give it a string. Then you can add the new button to the body of the document:

document.body.appendChild(

new MYAPP.dom.FancyButton('puuush')

);

This is all well and works fine, but then you decide you also want to be able to set some of the style properties of the button such as colors and fonts. You can end up with a definition like the following:

MYAPP.dom.FancyButton =

function (text, type, color, border, font) {

// ...

};

Now, using the constructor can become a little inconvenient, especially when you want to set the third and fifth parameter, but not the second or the fourth:

new MYAPP.dom.FancyButton(

'puuush', null, 'white', null, 'Arial');

A better approach is to use one config object parameter for all the settings. The function definition can become something like the following:

MYAPP.dom.FancyButton = function (text, conf) {

var type = conf.type || 'submit';

var font = conf.font || 'Verdana';

// ...

};

Using the constructor is given as follows:

var config = {

font: 'Arial, Verdana, sans-serif',

color: 'white'

};

new MYAPP.dom.FancyButton('puuush', config);

Another usage example is as follows:

document.body.appendChild(

new MYAPP.dom.FancyButton('dude', {color: 'red'})

);

As you can see, it's easy to set only some of the parameters and to switch around their order. In addition, the code is friendlier and easier to understand when you see the names of the parameters at the same place where you call the method.

A drawback of this pattern is the same as its strength. It's trivial to keep adding more parameters, which means trivial to abuse the technique. Once you have an excuse to add to this free-for-all bag of properties, you will find it tempting to keep adding some that are not entirely optional or some that are dependent on other properties.

As a rule of thumb, all these properties should be independent and optional. If you have to check all possible combinations inside your function ("oh, A is set, but A is only used if B is also set") this is a recipe for a large function body, which quickly becomes confusing and difficult, if not impossible, to test, because of all the combinations.

Private properties and methods

JavaScript doesn't have the notion of access modifiers, which set the privileges of the properties in an object. Other languages often have access modifiers such as:

· Public—all users of an object can access these properties (or methods)

· Private—only the object itself can access these properties

· Protected—only objects inheriting the object in question can access these properties

JavaScript doesn't have a special syntax to denote private properties or methods, but as discussed in Chapter 3, Functions, you can use local variables and methods inside a function and achieve the same level of protection.

Continuing with the example of the FancyButton constructor, you can have a local variable styles which contains all the defaults, and a local setStyle() function. These are invisible to the code outside of the constructor. Here's how FancyButton can make use of the local private properties:

var MYAPP = {};

MYAPP.dom = {};

MYAPP.dom.FancyButton = function (text, conf) {

var styles = {

font: 'Verdana',

border: '1px solid black',

color: 'black',

background: 'grey'

};

function setStyles(b) {

var i;

for (i in styles) {

if (styles.hasOwnProperty(i)) {

b.style[i] = conf[i] || styles[i];

}

}

}

conf = conf || {};

var b = document.createElement('input');

b.type = conf.type || 'submit';

b.value = text;

setStyles(b);

return b;

};

In this implementation, styles is a private property and setStyle() is a private method. The constructor uses them internally (and they can access anything inside the constructor), but they are not available to code outside of the function.

Privileged methods

Privileged methods (this term was coined by Douglas Crockford) are normal public methods that can access private methods or properties. They can act like a bridge in making some of the private functionality accessible but in a controlled manner, wrapped in a privileged method.

Private functions as public methods

Let us say you've defined a function that you absolutely need to keep intact, so you make it private. But, you also want to provide access to the same function so that outside code can also benefit from it. In this case, you can assign the private function to a publicly available property.

Let's define _setStyle() and _getStyle() as private functions, but then assign them to the public setStyle() and getStyle():

var MYAPP = {};

MYAPP.dom = (function () {

var _setStyle = function (el, prop, value) {

console.log('setStyle');

};

var _getStyle = function (el, prop) {

console.log('getStyle');

};

return {

setStyle: _setStyle,

getStyle: _getStyle,

yetAnother: _setStyle

};

}());

Now, when you call MYAPP.dom.setStyle(), it invokes the private _setStyle() function. You can also overwrite setStyle() from the outside:

MYAPP.dom.setStyle = function () {alert('b');};

Now, the result is as follows:

· MYAPP.dom.setStyle points to the new function

· MYAPP.dom.yetAnother still points to _setStyle()

· _setStyle() is always available when any other internal code relies on it to be working as intended, regardless of the outside code

When you expose something private, keep in mind that objects (and functions and arrays are objects too) are passed by reference and, therefore, can be modified from the outside.

Immediate functions

Another pattern that helps you keep the global namespace clean is to wrap your code in an anonymous function and execute that function immediately. This way any variables inside the function are local (as long as you use the var statement) and are destroyed when the function returns, if they aren't part of a closure. This pattern was discussed in more detail in Chapter 3, Functions. Have a look at the following code:

(function () {

// code goes here...

}());

This pattern is especially suitable for on-off initialization tasks performed when the script loads.

The immediate (self-executing) function pattern can be extended to create and return objects. If the creation of these objects is more complicated and involves some initialization work, then you can do this in the first part of the self-executable function and return a single object, which can access and benefit from any private properties in the top portion as follows:

var MYAPP = {};

MYAPP.dom = (function () {

// initialization code...

function _private() {

// ...

}

return {

getStyle: function (el, prop) {

console.log('getStyle');

_private();

},

setStyle: function (el, prop, value) {

console.log('setStyle');

}

};

}());

Modules

Combining several of the previous patterns, gives you a new pattern, commonly referred to as a module pattern. The concept of modules in programming is convenient as it allows you to code separate pieces or libraries and combine them as needed just like pieces of a puzzle.

Tip

Two notable facts beyond the scope of this chapter

JavaScript doesn't have a built-in concept of modules, although this is planned for the future via export and import declarations. There is also the module specification from http://www.commonjs.org, which defines a require() function and an exports object.

The module pattern includes:

· Namespaces to reduce naming conflicts among modules

· An immediate function to provide a private scope and initialization

· Private properties and methods

· Returning an object that has the public API of the module as follows:

· namespace('MYAPP.module.amazing');

·

· MYAPP.module.amazing = (function () {

·

· // short names for dependencies

· var another = MYAPP.module.another;

·

· // local/private variables

· var i, j;

·

· // private functions

· function hidden() {}

·

· // public API

· return {

· hi: function () {

· return "hello";

· }

· };

}());

And using the following module:

MYAPP.module.amazing.hi(); // "hello"

Chaining

Chaining is a pattern that allows you to invoke multiple methods on one line as if the methods are the links in a chain. This is convenient when calling several related methods. You invoke the next method on the result of the previous without the use of an intermediate variable.

Say you've created a constructor that helps you work with DOM elements. The code to create a new <span> and add it to the <body> could look something like the following:

var obj = new MYAPP.dom.Element('span');

obj.setText('hello');

obj.setStyle('color', 'red');

obj.setStyle('font', 'Verdana');

document.body.appendChild(obj);

As you know, constructors return the object referred to as this that they create. You can make your methods such as setText() and setStyle() also return this, which allows you to call the next method on the instance returned by the previous one. This way you can chain method calls:

var obj = new MYAPP.dom.Element('span');

obj.setText('hello')

.setStyle('color', 'red')

.setStyle('font', 'Verdana');

document.body.appendChild(obj);

You don't even need the obj variable if you don't plan on using it after the new element has been added to the tree, so the code looks like the following:

document.body.appendChild(

new MYAPP.dom.Element('span')

.setText('hello')

.setStyle('color', 'red')

.setStyle('font', 'Verdana')

);

A drawback of this pattern is that it makes it a little harder to debug when an error occurs somewhere in a long chain and you don't know which link is to blame because they are all on the same line.

JSON

Let's wrap up the coding patterns section of this chapter with a few words about JSON. JSON is not technically a coding pattern, but you can say that using JSON is a good pattern.

JSON is a popular lightweight format for exchanging data. It's often preferred over XML when using XMLHttpRequest() to retrieve data from the server. JSON stands for JavaScript Object Notation and there's nothing specifically interesting about it other than the fact that it's extremely convenient. The JSON format consists of data defined using object, and array literals. Here is an example of a JSON string that your server could respond with after an XHR request:

{

'name': 'Stoyan',

'family': 'Stefanov',

'books': ['OOJS', 'JSPatterns', 'JS4PHP']

}

An XML equivalent of this would be something like the following:

<?xml version="1.1" encoding="iso-8859-1"?>

<response>

<name>Stoyan</name>

<family>Stefanov</family>

<books>

<book>OOJS</book>

<book>JSPatterns</book>

<book>JS4PHP</book>

</books>

</response>

First, you can see how JSON is lighter in terms of the number of bytes. But, the main benefit is not the smaller byte size but the fact that it's trivial to work with JSON in JavaScript. Let's say you've made an XHR request and have received a JSON string in theresponseText property of the XHR object. You can convert this string of data into a working JavaScript object by simply using eval():

// warning: counter-example

var response = eval('(' + xhr.responseText + ')');

Now, you can access the data in obj as object properties:

console.log(response.name); // "Stoyan"

console.log(response.books[2]); // "JS4PHP"

The problem is that eval() is insecure, so it's best if you use the JSON object to parse the JSON data (a fallback for older browsers is available from http://json.org/). Creating an object from a JSON string is still trivial:

var response = JSON.parse(xhr.responseText);

To do the opposite, that is, to convert an object to a JSON string, you use the method stringify():

var str = JSON.stringify({hello: "you"});

Due to its simplicity, JSON has quickly become popular as a language-independent format for exchanging data and you can easily produce JSON on the server side using your preferred language. In PHP, for example, there are the functions json_encode() andjson_decode() that let you serialize a PHP array or object into a JSON string and vice versa.

Design patterns

The second part of this chapter presents a JavaScript approach to a subset of the design patterns introduced by the book called Design Patterns: Elements of Reusable Object-Oriented Software, an influential book most commonly referred to as the Book of Four or the Gang of Four, or GoF (after its four authors). The patterns discussed in the GoF book are divided into three groups:

· Creational patterns that deal with how objects are created (instantiated)

· Structural patterns that describe how different objects can be composed in order to provide new functionality

· Behavioral patterns that describe ways for objects to communicate with each other

There are 23 patterns in the Book of Four and more patterns have been identified since the book's publication. It's way beyond the scope of this book to discuss all of them, so the remainder of the chapter demonstrates only four, along with examples of their implementation in JavaScript. Remember that the patterns are more about interfaces and relationships rather than implementation. Once you have an understanding of a design pattern, it's often not difficult to implement it, especially in a dynamic language such as JavaScript.

The patterns discussed through the rest of the chapter are:

· Singleton

· Factory

· Decorator

· Observer

Singleton

Singleton is a creational design pattern meaning that its focus is on creating objects. It helps when you want to make sure there is only one object of a given kind (or class). In a classical language this would mean that an instance of a class is only created once and any subsequent attempts to create new objects of the same class would return the original instance.

In JavaScript, because there are no classes, a singleton is the default and most natural pattern. Every object is a singleton object.

The most basic implementation of the singleton in JavaScript is the object literal:

var single = {};

That was easy, right?

Singleton 2

If you want to use class-like syntax and still implement the singleton pattern, things become a bit more interesting. Let's say you have a constructor called Logger() and you want to be able to do something like the following:

var my_log = new Logger();

my_log.log('some event');

// ... 1000 lines of code later in a different scope ...

var other_log = new Logger();

other_log.log('some new event');

console.log(other_log === my_log); // true

The idea is that although you use new, only one instance needs to be created, and this instance is then returned in consecutive calls.

Global variable

One approach would be to use a global variable to store the single instance. Your constructor could look like this:

function Logger() {

if (typeof global_log === "undefined") {

global_log = this;

}

return global_log;

}

Using this constructor gives the expected result:

var a = new Logger();

var b = new Logger();

console.log(a === b); // true

The drawback is, obviously, the use of a global variable. It can be overwritten at any time, even accidentally, and you lose the instance. The opposite, your global variable overwriting someone else's is also possible.

Property of the Constructor

As you know, functions are objects and they have properties. You can assign the single instance to a property of the constructor function as follows:

function Logger() {

if (Logger.single_instance) {

Logger.single_instance = this;

}

return Logger.single_instance;

}

If you write var a = new Logger(), a points to the newly created Logger.single_instance property. A subsequent call var b = new Logger() results in b pointing to the same Logger.single_instance property, which is exactly what you want.

This approach certainly solves the global namespace issue because no global variables are created. The only drawback is that the property of the Logger constructor is publicly visible, so it can be overwritten at any time. In such cases, the single instance can be lost or modified. Of course, you can only provide so much protection against fellow programmers shooting themselves in the foot. After all, if someone can mess with the single instance property, they can mess up the Logger constructor directly, as well.

In a private property

The solution to the problem of overwriting the publicly visible property is not to use a public property but a private one. You already know how to protect variables with a closure, so as an exercise you can implement this approach to the singleton pattern.

Factory

The factory is another creational design pattern as it deals with creating objects. The factory can help when you have similar types of objects and you don't know in advance which one you want to use. Based on user input or other criteria, your code determines the type of object it needs on the fly.

Let's say you have three different constructors, which implement similar functionality. All the objects they create take a URL but do different things with it. One creates a text DOM node, the second creates a link, and the third an image as follows:

var MYAPP = {};

MYAPP.dom = {};

MYAPP.dom.Text = function (url) {

this.url = url;

this.insert = function (where) {

var txt = document.createTextNode(this.url);

where.appendChild(txt);

};

};

MYAPP.dom.Link = function (url) {

this.url = url;

this.insert = function (where) {

var link = document.createElement('a');

link.href = this.url;

link.appendChild(document.createTextNode(this.url));

where.appendChild(link);

};

};

MYAPP.dom.Image = function (url) {

this.url = url;

this.insert = function (where) {

var im = document.createElement('img');

im.src = this.url;

where.appendChild(im);

};

};

Using the three different constructors is exactly the same, pass the url and call the insert() method:

var url = 'http://www.phpied.com/images/covers/oojs.jpg';

var o = new MYAPP.dom.Image(url);

o.insert(document.body);

var o = new MYAPP.dom.Text(url);

o.insert(document.body);

var o = new MYAPP.dom.Link(url);

o.insert(document.body);

Imagine your program doesn't know in advance which type of object is required. The user decides, during runtime, by clicking on a button for example. If type contains the required type of object, you'll need to use an if or a switch, and do something like this:

var o;

if (type === 'Image') {

o = new MYAPP.dom.Image(url);

}

if (type === 'Link') {

o = new MYAPP.dom.Link(url);

}

if (type === 'Text') {

o = new MYAPP.dom.Text(url);

}

o.url = 'http://...';

o.insert();

This works fine, but if you have a lot of constructors, the code becomes too lengthy and hard to maintain. Also, if you are creating a library or a framework that allows extensions or plugins, you don't even know the exact names of all the constructor functions in advance. In such cases, it's convenient to have a factory function that takes care of creating an object of the dynamically determined type:

Let's add a factory method to the MYAPP.dom utility:

MYAPP.dom.factory = function (type, url) {

return new MYAPP.dom[type](url);

};

Now, you can replace the three if functions with the simpler code as follows:

var image = MYAPP.dom.factory("Image", url);

image.insert(document.body);

The example factory() method in the previous code was simple, but in a real life scenario you'd want to do some validation against the type value (for example, check if MYAPP.dom[type] exists) and optionally do some setup work common to all object types (for example, setup the URL all constructors use).

Decorator

The Decorator design pattern is a structural pattern; it doesn't have much to do with how objects are created but rather how their functionality is extended. Instead of using inheritance where you extend in a linear way (parent-child-grandchild), you can have one base object and a pool of different decorator objects that provide extra functionality. Your program can pick and choose which decorators it wants and in which order. For a different program or code path, you might have a different set of requirements and pick different decorators out of the same pool. Take a look at how the usage part of the decorator pattern could be implemented:

var obj = {

doSomething: function () {

console.log('sure, asap');

}

// ...

};

obj = obj.getDecorator('deco1');

obj = obj.getDecorator('deco13');

obj = obj.getDecorator('deco5');

obj.doSomething();

You can see how you can start with a simple object that has a doSomething() method. Then you can pick one of the decorator objects you have lying around and can be identified by name. All decorators provide a doSomething() method which first calls the same method of the previous decorator and then proceeds with its own code. Every time you add a decorator, you overwrite the base obj with an improved version of it. At the end, when you are finished adding decorators, you call doSomething(). As a result all of thedoSomething() methods of all the decorators are executed in sequence. Let's see an example.

Decorating a Christmas tree

Let's illustrate the decorator pattern with an example of decorating a Christmas tree. You start with the decorate() method as follows:

var tree = {};

tree.decorate = function () {

alert('Make sure the tree won\'t fall');

};

Now, let's implement a getDecorator() method which adds extra decorators. The decorators will be implemented as constructor functions, and they'll all inherit from the base tree object:

tree.getDecorator = function (deco) {

tree[deco].prototype = this;

return new tree[deco];

};

Now, let's create the first decorator, RedBalls(), as a property of tree (in order to keep the global namespace cleaner). The red ball objects also provide a decorate() method, but they make sure they call their parent's decorate() first:

tree.RedBalls = function () {

this.decorate = function () {

this.RedBalls.prototype.decorate();

alert('Put on some red balls');

};

};

Similarly, implementing BlueBalls() and Angel() decorators:

tree.BlueBalls = function () {

this.decorate = function () {

this.BlueBalls.prototype.decorate();

alert('Add blue balls');

};

};

tree.Angel = function () {

this.decorate = function () {

this.Angel.prototype.decorate();

alert('An angel on the top');

};

};

Now, let's add all of the decorators to the base object:

tree = tree.getDecorator('BlueBalls');

tree = tree.getDecorator('Angel');

tree = tree.getDecorator('RedBalls');

Finally, running the decorate() method:

tree.decorate();

This single call results in the following alerts (in this order):

· Make sure the tree won't fall

· Add blue balls

· An angel on the top

· Add some red balls

As you see, this functionality allows you to have as many decorators as you like, and to choose and combine them in any way you like.

Observer

The observer pattern (also known as the subscriber-publisher pattern) is a behavioral pattern, which means that it deals with how different objects interact and communicate with each other. When implementing the observer pattern you have the following objects:

· One or more publisher objects that announce when they do something important.

· One or more subscribers tuned in to one or more publishers. They listen to what the publishers announce and then act appropriately.

The observer pattern may look familiar to you. It sounds similar to the browser events discussed in the previous chapter, and rightly so, because the browser events are one example application of this pattern. The browser is the publisher, it announces the fact that an event (such as a click) has happened. Your event listener functions that are subscribed to (listen to) this type of event will be notified when the event happens. The browser-publisher sends an event object to all of the subscribers. In your custom implementations you can send any type of data you find appropriate.

There are two subtypes of the observer pattern, push and pull. Push is where the publishers are responsible for notifying each subscriber, and pull is where the subscribers monitor for changes in a publisher's state.

Let's take a look at an example implementation of the push model. Let's keep the observer-related code into a separate object and then use this object as a mix-in, adding its functionality to any other object that decides to be a publisher. In this way any object can become a publisher and any function can become a subscriber. The observer object will have the following properties and methods:

· An array of subscribers that are just callback functions

· addSubscriber() and removeSubscriber() methods that add to, and remove from, the subscribers collection

· A publish() method that takes data and calls all subscribers, passing the data to them

· A make() method that takes any object and turns it into a publisher by adding all of the methods mentioned previously to it

Here's the observer mix-in object, which contains all the subscription-related methods and can be used to turn any object into a publisher:

var observer = {

addSubscriber: function (callback) {

if (typeof callback === "function") {

this.subscribers[this.subscribers.length] = callback;

}

},

removeSubscriber: function (callback) {

for (var i = 0; i < this.subscribers.length; i++) {

if (this.subscribers[i] === callback) {

delete this.subscribers[i];

}

}

},

publish: function (what) {

for (var i = 0; i < this.subscribers.length; i++) {

if (typeof this.subscribers[i] === 'function') {

this.subscribers[i](what);

}

}

},

make: function (o) { // turns an object into a publisher

for (var i in this) {

if (this.hasOwnProperty(i)) {

o[i] = this[i];

o.subscribers = [];

}

}

}

};

Now, let's create some publishers. A publisher can be any object and its only duty is to call the publish() method whenever something important occurs. Here's a blogger object which calls publish() every time a new blog posting is ready:

var blogger = {

writeBlogPost: function() {

var content = 'Today is ' + new Date();

this.publish(content);

}

};

Another object could be the LA Times newspaper which calls publish() when a new newspaper issue is out:

var la_times = {

newIssue: function() {

var paper = 'Martians have landed on Earth!';

this.publish(paper);

}

};

Turning these objects into publishers:

observer.make(blogger);

observer.make(la_times);

Now, let's have two simple objects jack and jill:

var jack = {

read: function(what) {

console.log("I just read that " + what)

}

};

var jill = {

gossip: function(what) {

console.log("You didn't hear it from me, but " + what)

}

};

jack and jill can subscribe to the blogger object by providing the callback methods they want to be called when something is published:

blogger.addSubscriber(jack.read);

blogger.addSubscriber(jill.gossip);

What happens now when the blogger writes a new post? The result is that jack and jill get notified:

> blogger.writeBlogPost();

I just read that Today is Fri Jan 04 2013 19:02:12 GMT-0800 (PST)

You didn't hear it from me, but Today is Fri Jan 04 2013 19:02:12 GMT-0800 (PST)

At any time, jill may decide to cancel her subscription. Then, when writing another blog post, the unsubscribed object is no longer notified:

> blogger.removeSubscriber(jill.gossip);

> blogger.writeBlogPost();

I just read that Today is Fri Jan 04 2013 19:03:29 GMT-0800 (PST)

jill may decide to subscribe to LA Times as an object can be a subscriber to many publishers:

> la_times.addSubscriber(jill.gossip);

Then, when LA Times publishes a new issue, jill gets notified and jill.gossip() is executed:

> la_times.newIssue();

You didn't hear it from me, but Martians have landed on Earth!

Summary

In this chapter, you learned about common JavaScript coding patterns and learned how to make your programs cleaner, faster, and better at working with other programs and libraries. Then you saw a discussion and sample implementations of a handful of the design patterns from the Book of Four. You can see how JavaScript is a fully featured dynamic programming language and that implementing classical patterns in a dynamic loosely typed language is pretty easy. The patterns are, in general, a large topic and you can join the author of this book in a further discussion of the JavaScript patterns at the website JSPatterns.com or take a look at the book appropriately named "JavaScript Patterns".