Top JavaScript Patterns Every Developer Should Know.

Every developer strives to write maintainable, readable, and reusable code. Code structuring becomes more important as applications become larger. Design patterns prove crucial to solving this challenge – providing an organization structure for common issues in a particular circumstance.

design pattern is used to identify reusable solutions that can be applied to recurring problems that software developers commonly face during software design. They represent time-tested solutions and best practices adopted by object-oriented software developers over time.

JavaScript Constructor Pattern

In classical object-oriented programming languages, a 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, we’re most often interested in object constructors.

Object constructors are used to create specific types of objects—both preparing the object for use and accepting arguments a constructor can use to set the values of member properties and methods when the object is first created.

JavaScript doesn’t support the concept of classes, but it does support special constructor functions that work with objects. By simply prefixing a call to a constructor function with the keyword new, we can tell JavaScript we would like the function to behave like a constructor and instantiate a new object with the members defined by that function.

Inside a constructor, the keyword this references the new object that’s being created. Revisiting object creation, a basic constructor may look as follows:



function Car( model, year, miles ) {

  this.model = model;
  this.year = year;
  this.miles = miles;

  this.toString = function () {
    return this.model + " has done " + this.miles + " miles";
  };
}

// Usage:

// We can create new instances of the car
var civic = new Car( "Honda Civic", 2009, 20000 );
var mondeo = new Car( "Ford Mondeo", 2010, 5000 );

// and then open our browser console to view the 
// output of the toString() method being called on 
// these objects
console.log( civic.toString() );
console.log( mondeo.toString() );

The above is a simple version of the constructor pattern, but it does suffer from some problems. One is that it makes inheritance difficult and the other is that functions such as toString() are redefined for each of new object created using the Car constructor. This isn’t optimal, as the function should ideally be shared between all instances of the Car type.

Thankfully, as there are a number of both ES3- and ES5-compatible alternatives to constructing objects, it’s trivial to work around this limitation.

Constructors with Prototypes

Functions in JavaScript have a property called a prototype. 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. In this fashion, multiple Car objects can be created that access the same prototype. We can thus extend the original example as follows:



function Car( model, year, miles ) {

  this.model = model;
  this.year = year;
  this.miles = miles;

}


// Note here that we are using Object.prototype.newMethod rather than 
// Object.prototype so as to avoid redefining the prototype object
Car.prototype.toString = function () {
  return this.model + " has done " + this.miles + " miles";
};

// Usage:

var civic = new Car( "Honda Civic", 2009, 20000 );
var mondeo = new Car( "Ford Mondeo", 2010, 5000 );

console.log( civic.toString() );
console.log( mondeo.toString() );

A single instance of toString() will now be shared between all Car objects.

JavaScript Module Pattern

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.

In JavaScript, there are several options for implementing modules. These include:

  • Object literal notation
  • The Module pattern
  • AMD modules
  • CommonJS modules
  • ECMAScript Harmony modules

The Module pattern is based in part on object literals, so it makes sense to refresh our knowledge of them first.

Object Literals

In object literal notation, an object is described as a set of comma-separated name/value pairs enclosed in curly braces ({}). Names inside the object may be either strings or identifiers that are followed by a colon. There should be no comma used after the final name/value pair in the object, as this may result in errors.



var myObjectLiteral = {

    variableKey: variableValue,

    functionKey: function () {
      // ...
    };
};

Object literals don’t require instantiation using the new operator, but shouldn’t be used at the start of a statement, as the opening { may be interpreted as the beginning of a block. Outside of an object, new members may be added to the object literal using assignment as follows: myModule.property = "someValue";

Below, we can see a more complete example of a module defined using object literal notation:



var myModule = {

  myProperty: "someValue",

  // object literals can contain properties and methods.
  // e.g we can define a further object for module configuration:
  myConfig: {
    useCaching: true,
    language: "en"
  },

  // a very basic method
  myMethod: function () {
    console.log( "Where in the world is Paul Irish today?" );
  },

  // output a value based on the current configuration
  myMethod2: function () {
    console.log( "Caching is:" + ( this.myConfig.useCaching ) ? "enabled" : "disabled" );
  },

  // override the current configuration
  myMethod3: function( newConfig ) {

    if ( typeof newConfig === "object" ) {
      this.myConfig = newConfig;
      console.log( this.myConfig.language );
    }
  }
};

// Outputs: Where in the world is Paul Irish today?
myModule.myMethod();

// Outputs: enabled
myModule.myMethod2();

// Outputs: fr
myModule.myMethod3({
  language: "fr",
  useCaching: false
});

Using object literals can assist in encapsulating and organizing your code. Rebecca Murphey has previously written about this topic in depth, should you wish to read into object literals further.

That said, if we’re opting for this technique, we may be equally as interested in the Module pattern. It still uses object literals but only as the return value from a scoping function.

JavaScript Module Pattern

The Module pattern was originally defined as a way to provide both private and public encapsulation for classes in conventional software engineering.

In JavaScript, the Module pattern is used to further emulate the concept of classes in such a way that we’re able to include both public/private methods and variables inside a single object, thus shielding particular parts from the global scope.

Privacy

The Module pattern encapsulates “privacy” state and organization using closures. It provides a way of wrapping a mix of public and private methods and variables, protecting pieces from leaking into the global scope and accidentally colliding with another developer’s interface. With this pattern, only a public API is returned, keeping everything else within the closure private.

This gives us a clean solution for shielding logic doing the heavy lifting while only exposing an interface we would like other parts of our application to use. The pattern is quite similar to an immediately-invoked functional expression[1] , except that an object is returned rather than a function.

It should be noted that there isn’t really an explicitly true sense of “privacy” inside JavaScript because unlike some traditional languages, it doesn’t have access modifiers. Variables can’t technically be declared as being public nor private, and so we use function scope to simulate this concept. Within the Module pattern, variables or methods declared are only available inside the module itself, thanks to closure. Variables or methods defined within the returning object, however, are available to everyone.

History

From a historical perspective, the Module pattern was originally developed by a number of people, including Richard Cornford in 2003. It was later popularized by Douglas Crockford in his lectures. In addition, if you’ve ever played with Yahoo’s YUI library, some of its features may appear quite familiar, because the Module pattern was a strong influence for YUI when creating their components.

Examples

Let’s begin looking at an implementation of the Module pattern by creating a module that is self-contained.



var testModule = (function () {

  var counter = 0;

  return {

    incrementCounter: function () {
      return ++counter;
    },

    resetCounter: function () {
      console.log( "counter value prior to reset: " + counter );
      counter = 0;
    }
  };

})();

// Usage:

// Increment our counter
testModule.incrementCounter();

// Check the counter value and reset
// Outputs: 1
testModule.resetCounter();

Here, other parts of the code are unable to directly read the value of our incrementCounter() or resetCounter(). The counter variable is actually fully shielded from our global scope so it acts just like a private variable would—its existence is limited to within the module’s closure so that the only code able to access its scope, are our two functions. Our methods are effectively namespaced so in the test section of our code, we need to prefix any calls with the name of the module (e.g., testModule).

When working with the Module pattern, we may find it useful to define a simple template for getting started with it. Here’s one that covers namespacing, public, and private variables:


var myNamespace = (function () {


  // A private counter variable
  var myPrivateVar = 0;

  // A private function which logs any arguments
  var myPrivateMethod = function( foo ) {
      console.log( foo );
  };

  return {

    // A public variable
    myPublicVar: "foo",

    // A public function utilizing privates
    myPublicFunction: function( bar ) {

      // Increment our private counter
      myPrivateVar++;

      // Call our private method using bar
      myPrivateMethod( bar );

    }
  };

})();

Looking at another example, we can see a shopping basket implemented using this pattern. The module itself is completely self-contained in a global variable called basketModule. The basket array in the module is kept private, so other parts of our application are unable to directly read it. It only exists with the module’s closure, so the only methods able to access it are those with access to its scope (i.e., addItem()getItem(), etc.).


var basketModule = (function () {

  // privates

  var basket = []; 

  function doSomethingPrivate() {
    //...
  }

  function doSomethingElsePrivate() {
    //...
  }

  // Return an object exposed to the public
  return { 

    // Add items to our basket
    addItem: function( values ) {
      basket.push(values);
    },

    // Get the count of items in the basket
    getItemCount: function () {
      return basket.length;
    },

    // Public alias to a  private function
    doSomething: doSomethingPrivate,

    // Get the total value of items in the basket
    getTotal: function () {

      var itemCount = this.getItemCount(),
          total = 0;

      while (itemCount--) {
        total += basket[itemCount].price;
      }

      return total;
    }
  };
}());

Inside the module, you may have noticed that we return an object. This gets automatically assigned to basketModule so that we can interact with it as follows:


// basketModule returns an object with a public API we can use

basketModule.addItem({
  item: "bread",
  price: 0.5
});

basketModule.addItem({
  item: "butter",
  price: 0.3
});

// Outputs: 2
console.log( basketModule.getItemCount() );

// Outputs: 0.8
console.log( basketModule.getTotal() );

// However, the following will not work:

// Outputs: undefined
// This is because the basket itself is not exposed as a part of our
// the public API
console.log( basketModule.basket ); 

// This also won't work as it only exists within the scope of our
// basketModule closure, but not the returned public object
console.log( basket );

The methods above are effectively namespaced inside basketModule.

Notice how the scoping function in the above basket module is wrapped around all of our functions, which we then call and immediately store the return value of. This has a number of advantages including:

  • The freedom to have private functions that can only be consumed by our module. As they aren’t exposed to the rest of the page (only our exported API is), they’re considered truly private.
  • Given that functions are declared normally and are named, it can be easier to show call stacks in a debugger when we’re attempting to discover what function(s) threw exceptions.
  • As T.J. Crowder has pointed out in the past, it also enables us to return different functions depending on the environment. In the past, I’ve seen developers use this to perform UA testing to provide a codepath in their module specific to IE, but we can easily opt for feature detection these days to achieve a similar goal.

Module Pattern Variations

Import mixins

This variation of the pattern demonstrates how globals (e.g., jQueryUnderscore) can be passed in as arguments to our module’s anonymous function. This effectively allows us to import them and locally alias them as we wish.



// Global module
var myModule = (function ( jQ, _ ) {
  
    function privateMethod1(){
        jQ(".container").html("test");
    }

    function privateMethod2(){
      console.log( _.min([10, 5, 100, 2, 1000]) );
    }
    
    return{
        publicMethod: function(){
            privateMethod1();                
        }            
    };
   
// Pull in jQuery and Underscore
}( jQuery, _ ));

myModule.publicMethod();

Exports

This next variation allows us to declare globals without consuming them and could similarly support the concept of global imports seen in the last example.


// Global module
var myModule = (function () {

    // Module object 
  var module = {},
    privateVariable = "Hello World";
  
  function privateMethod() {
    // ...
  }

  module.publicProperty = "Foobar";
  module.publicMethod = function () {
    console.log( privateVariable );
  };
  
  return module;

}());

JavaScript Revealing Module Pattern

One thing that the revealing module can do is avoiding repeat the name of the main object when we want to call one public method from another or access public variables.



var myRevealingModule = (function() {
  var privateVariable = 'not okay',
    publicVariable = 'okay';
  function privateFun() {
    return privateVariable;
  }

  function publicSetName(strName) {
    privateVariable = strName;
  }

  function publicGetName() {
    privateFun();
  }

  return {
    setName: publicSetName,
    message: publicVariable,
    getName: publicGetName
  };
})();

//Usage:

myRevealingModule.setName('Marvin King');

Advantages

We’ve seen why the Singleton pattern can be useful, but why is the Module pattern a good choice? For starters, it’s a lot cleaner for developers coming from an object-oriented background than the idea of true encapsulation, at least from a JavaScript perspective.

Second, it supports private data—so, in the Module pattern, public parts of our code are able to touch the private parts, however the outside world is unable to touch the class’s private parts (thanks to David Engfer for the joke).

Disadvantages

The disadvantages of the Module pattern are that, as we access both public and private members differently, when we wish to change visibility, we actually have to make changes to each place the member was used.

We also can’t access private members in methods that are added to the object at a later point. That said, in many cases, the Module pattern is still quite useful and, when used correctly, certainly has the potential to improve the structure of our application.

Other disadvantages include the inability to create automated unit tests for private members and additional complexity when bugs require hot fixes. It’s simply not possible to patch privates. Instead, one must override all public methods that interact with the buggy privates. Developers can’t easily extend privates either, so it’s worth remembering privates are not as flexible as they may initially appear.

For further reading on the Module pattern, see Ben Cherry’s excellent in-depth article.

JavaScript Singleton Pattern

The Singleton pattern is thus known because it restricts instantiation of a class to single object. Singletons differ from static classes as we can delay their initialization. generally because they require some information that may not be available during initialization time. For code that is unaware of a previous reference to them, they do not provide a method for easy retrieval. Let’s have a look of the structure of singleton:



var singletonPattern = (function() {
  var instance;
  function init() {
    // Singleton
    function privateMethod() {
      console.log('privateMethod');
    }
    var privateVariable = 'this is private variable';
    var privateRandomNumber = Math.random();
    return {
      publicMethod: function() {
        console.log('publicMethod');
      },
      publicProperty: 'this is public property',
      getRandomNumber: function() {
        return privateRandomNumber;
      }
    };
  }

  return {
    // Get the singleton instance if one exists
    // or create if it doesn't
    getInstance: function() {
      if (!instance) {
        instance = init();
      }
      return instance;
    }
  };
})();

// Usage:
var single = singletonPattern.getInstance();

JavaScript Observer Pattern

The Observer pattern offers a subscription model in which objects subscribe to an event and get notified when the event occurs. This pattern is the cornerstone of event driven programming, including JavaScript. The Observer pattern facilitates good object-oriented design and promotes loose coupling.

Using Observer

When building web apps you end up writing many event handlers. Event handlers are functions that will be notified when a certain event fires. These notifications optionally receive an event argument with details about the event (for example the x and y position of the mouse at a click event).

The event and event-handler paradigm in JavaScript is the manifestation of the Observer design pattern. Another name for the Observer pattern is Pub/Sub, short for Publication/Subscription.

Participants

The objects participating in this pattern are:

  • Subject — In example code: Click
    • maintains list of observers. Any number of Observer objects may observe a Subject
    • implements an interface that lets observer objects subscribe or unsubscribe
    • sends a notification to its observers when its state changes
  • Observers — In example code: clickHandler
    • has a function signature that can be invoked when Subject changes (i.e. event occurs)

Example

The Click object represents the Subject. The clickHandler function is the subscribing Observer. This handler subscribes, unsubscribes, and then subscribes itself while events are firing. It gets notified only of events #1 and #3.

Notice that the fire method accepts two arguments. The first one has details about the event and the second one is the context, that is, the this value for when the eventhandlers are called. If no context is provided this will be bound to the global object (window).



function Click() {
    this.handlers = [];  // observers
}

Click.prototype = {

    subscribe: function (fn) {
        this.handlers.push(fn);
    },

    unsubscribe: function (fn) {
        this.handlers = this.handlers.filter(
            function (item) {
                if (item !== fn) {
                    return item;
                }
            }
        );
    },

    fire: function (o, thisObj) {
        var scope = thisObj || window;
        this.handlers.forEach(function (item) {
            item.call(scope, o);
        });
    }
}

function run() {

    var clickHandler = function (item) {
        console.log("fired: " + item);
    };

    var click = new Click();

    click.subscribe(clickHandler);
    click.fire('event #1');
    click.unsubscribe(clickHandler);
    click.fire('event #2');
    click.subscribe(clickHandler);
    click.fire('event #3');
}

The observer is a design pattern in which an object maintains a list of objects depending on it observers, automatically notifying them of any changes to state.

  • Subject
    • Maintains a list of observers, facilities adding or removing observers
  • Observer
    • Provides an update interface for object that need to be notified of a subject’s change of state
  • ConcreteSubject
    • Broadcasts notifications to Observers on changes of state, stores the state of ConcreteObservers
  • ConcreteObserver
    • Stores a reference to the ConcreteSubject, implements an update interface for the observer to ensure state is consistent with subjects

function ObserverList() {
  this.observerList = [];
}

ObserverList.prototype.Add = function(obj) {
  return this.observerList.push(obj);
};

ObserverList.prototype.Empty = function() {
  this.observerList = [];
};

ObserverList.prototype.Count = function() {
  return this.observerList.length;
};

ObserverList.prototype.Get = function(index) {
  if (index > -1 && index < this.observerList.length) {
    return this.observerList[index];
  }
};

When a subject needs to notify observers about something interesting happening, it broadcasts a notification to the observers ( including specific data related to the topic of the notification)

When we no longer wish for a particular observer the notified of changes by the subject it is registered with, the subject can remove it from the list of observers. In the future, I will talk more about the feature of how the observer can be used in JavaScript widely.

JavaScript Mediator Pattern

The dictionary refers to a mediator as “a neutral party that assists in negotiations and conflict resolution.”[2] 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.

If it appears a system has too many direct relationships between components, it may be time to have a central point of control that components communicate through instead. The Mediator pattern promotes loose coupling by ensuring that instead of components referring to each other explicitly, their interaction is handled through this central point. This can help us decouple systems and improve the potential for component reusability.

A real-world analogy could be a typical airport traffic control system. A tower (mediator) handles which planes can take off and land, because all communications (notifications being listened for or broadcast) are performed from the planes to the control tower, rather than from plane to plane.

In implementation terms, the Mediator pattern is essentially a shared subject in the Observer pattern. This might assume that a direction Publish/Subscribe relationship between objects or modules in such systems is sacrificed in order to maintain a central point of contact.

It may also be considered supplemental—perhaps used for application-level notifications such as a communication between different subsystems that are themselves complex and may desire internal component decoupling through Publish/Subscribe relationships.

Another analogy would be DOM event bubbling and event delegation. If all subscriptions in a system are made against the document rather than individual nodes, the document effectively serves as a mediator. Instead of binding to the events of the individual nodes, a higher level object is given the responsibility of notifying subscribers about interaction events.

Basic Implementation

A simple implementation of the Mediator pattern can be found below, exposing both publish() and subscribe() methods for use:

var mediator = (function(){

    // Storage for topics that can be broadcast or listened to
    var topics = {};

    // Subscribe to a topic, supply a callback to be executed
    // when that topic is broadcast to
    var subscribe = function( topic, fn ){

        if ( !topics[topic] ){ 
          topics[topic] = [];
        }

        topics[topic].push( { context: this, callback: fn } );

        return this;
    };

    // Publish/broadcast an event to the rest of the application
    var publish = function( topic ){

        var args;

        if ( !topics[topic] ){
          return false;
        } 

        args = Array.prototype.slice.call( arguments, 1 );
        for ( var i = 0, l = topics[topic].length; i < l; i++ ) {

            var subscription = topics[topic][i];
            subscription.callback.apply( subscription.context, args );
        }
        return this;
    };

    return {
        publish: publish,
        subscribe: subscribe,
        installTo: function( obj ){
            obj.subscribe = subscribe;
            obj.publish = publish;
        }
    };

}());

Advanced Implementation

For those interested in a more advanced implementation, read on for a walkthrough of my trimmed-down version of Jack Lawson’s excellent Mediator.js. Among other improvements, this version supports topic namespaces, subscriber removal, and a much more robust Publish/Subscribe system for our Mediator. If however, you wish to skip this walkthrough, you can go directly to the next example to continue reading.[3]

To start, let’s implement the notion of a subscriber, which we can consider an instance of a Mediator’s topic registration.

By generating object instances, we can easily update subscribers later without the need to unregister and re-register them. Subscribers can be written as constructors that take a function fn to be called, an options object, and a context.

// Pass in a context to attach our Mediator to. 
// By default this will be the window object
(function( root ){
   
  function guidGenerator() { /*..*/}

  // Our Subscriber constructor
  function Subscriber( fn, options, context ){

    if ( !this instanceof Subscriber ) {

      return new Subscriber( fn, context, options );

    }else{

      // guidGenerator() is a function that generates 
      // GUIDs for instances of our Mediators Subscribers so
      // we can easily reference them later on. We're going
      // to skip its implementation for brevity

      this.id = guidGenerator();
      this.fn = fn;
      this.options = options;
      this.context = context;
      this.topic = null;

    }
  }
})();

Topics in our Mediator hold a list of callbacks and subtopics that are fired when Mediator.Publish is called on our Mediator instance. It also contains methods for manipulating lists of data.

// Let's model the Topic.
// JavaScript lets us use a Function object as a 
// conjunction of a prototype for use with the new 
// object and a constructor function to be invoked.
function Topic( namespace ){

  if ( !this instanceof Topic ) {
    return new Topic( namespace );
  }else{

    this.namespace = namespace || "";
    this._callbacks = [];
    this._topics = [];
    this.stopped = false;

  }
}


// Define the prototype for our topic, including ways to
// add new subscribers or retrieve existing ones.
Topic.prototype = {

  // Add a new subscriber 
  AddSubscriber: function( fn, options, context ){

    var callback = new Subscriber( fn, options, context );

    this._callbacks.push( callback );

    callback.topic = this;

    return callback;
  },
...

Our topic instance is passed along as an argument to the Mediator callback. Further callback propagation can then be called using a handy utility method called StopPropagation():

   StopPropagation: function(){
      this.stopped = true;
    },

We can also make it easy to retrieve existing subscribers when given a GUID identifier:

  GetSubscriber: function( identifier ){

      for(var x = 0, y = this._callbacks.length; x < y; x++ ){
        if( this._callbacks[x].id == identifier || this._callbacks[x].fn == identifier ){
          return this._callbacks[x];
        }
      }

      for( var z in this._topics ){
        if( this._topics.hasOwnProperty( z ) ){
          var sub = this._topics[z].GetSubscriber( identifier );
          if( sub !== undefined ){
            return sub;
          }
        }
      }

    },

Next, in case we need them, we can offer easy ways to add new topics, check for existing topics, or retrieve topics:

    AddTopic: function( topic ){
      this._topics[topic] = new Topic( (this.namespace ? this.namespace + ":" : "") + topic );
    },

    HasTopic: function( topic ){
      return this._topics.hasOwnProperty( topic );
    },

    ReturnTopic: function( topic ){
      return this._topics[topic];
    },

We can explicitly remove subscribers if we feel they are no longer necessary. The following will recursively remove a Subscriber through its subtopics:

    RemoveSubscriber: function( identifier ){

      if( !identifier ){
        this._callbacks = [];

        for( var z in this._topics ){
          if( this._topics.hasOwnProperty(z) ){
            this._topics[z].RemoveSubscriber( identifier );
          }
        }
      }

      for( var y = 0, x = this._callbacks.length; y < x; y++ ) {
        if( this._callbacks[y].fn == identifier || this._callbacks[y].id == identifier ){
          this._callbacks[y].topic = null;
          this._callbacks.splice( y,1 );
          x--; y--;
        }
      }

    },

Next, we include the ability to Publish arbitrary arguments to subscribers recursively through subtopics.

  Publish: function( data ){

      for( var y = 0, x = this._callbacks.length; y < x; y++ ) {

          var callback = this._callbacks[y], l;
            callback.fn.apply( callback.context, data );

        l = this._callbacks.length;

        if( l < x ){
          y--; 
          x = l;
        }
      }

      for( var x in this._topics ){
        if( !this.stopped ){
          if( this._topics.hasOwnProperty( x ) ){
            this._topics[x].Publish( data );
          }
        }
      }

      this.stopped = false;
    }
  };

Here we expose the Mediator instance we will primarily be interacting with. It is through here that events are registered and removed from topics.

  function Mediator() {

    if ( !this instanceof Mediator ) {
      return new Mediator();
    }else{
      this._topics = new Topic( "" );
    }

  };

For more advanced-use cases, we can get our Mediator supporting namespaces for topics such as inbox:messages:new:read.GetTopic, which in the following example, returns topic instances based on a namespace.

Mediator.prototype = {

    GetTopic: function( namespace ){
      var topic = this._topics,
          namespaceHierarchy = namespace.split( ":" );

      if( namespace === "" ){
        return topic;
      }

      if( namespaceHierarchy.length > 0 ){
        for( var i = 0, j = namespaceHierarchy.length; i < j; i++ ){

          if( !topic.HasTopic( namespaceHierarchy[i]) ){
            topic.AddTopic( namespaceHierarchy[i] );
          }

          topic = topic.ReturnTopic( namespaceHierarchy[i] );
        }
      }

      return topic;
    },

In this section, we define a Mediator.Subscribe method, which accepts a topic namespace, a function fn to be executed, options, and once again a context to call the function into Subscribe. This creates a topic if one doesn’t exist.

  Subscribe: function( topiclName, fn, options, context ){
      var options = options || {},
          context = context || {},
          topic = this.GetTopic( topicName ),
          sub = topic.AddSubscriber( fn, options, context );

      return sub;
    },

Continuing on from this, we can define further utilities for accessing specific subscribers or removing them from topics recursively.

    // Returns a subscriber for a given subscriber id / named function and topic namespace

    GetSubscriber: function( identifier, topic ){
      return this.GetTopic( topic || "" ).GetSubscriber( identifier );
    },

    // Remove a subscriber from a given topic namespace recursively based on
    // a provided subscriber id or named function.

    Remove: function( topicName, identifier ){
      this.GetTopic( topicName ).RemoveSubscriber( identifier );
    },

Our primary Publish method allows us to arbitrarily publish data to a chosen topic namespace.

Topics are called recursively downward. For example, a post to inbox:messages will post to inbox:messages:new and inbox:messages:new:read. It is used as follows:

    Mediator.Publish( "inbox:messages:new", [args] );
    Publish: function( topicName ){
      var args = Array.prototype.slice.call( arguments, 1),
          topic = this.GetTopic( topicName );

      args.push( topic );

      this.GetTopic( topicName ).Publish( args );
    }
  };

Finally we can easily expose our Mediator for attachment to the object passed in to root:

  root.Mediator = Mediator;
  Mediator.Topic = Topic;
  Mediator.Subscriber = Subscriber;

// Remember we can pass anything in here. I've passed in window to
// attach the Mediator to, but we can just as easily attach it to another
// object if desired.
})( window );

Example

Using either of the implementations from above (both the simple option and the more advanced one), we can then put together a simple chat logging system as follows.

Here is the HTML code:

 <h1>Chat</h1>
<form id="chatForm">
    <label for="fromBox">Your Name:</label>
    <input id="fromBox" type="text"/>
    <br />
    <label for="toBox">Send to:</label>
    <input id="toBox" type="text"/>
    <br />
    <label for="chatBox">Message:</label>
    <input id="chatBox" type="text"/>
    <button type="submit">Chat</button>
</form>

<div id="chatResult"></div>

Here is the JavaScript code:

$( "#chatForm" ).on( "submit", function(e) {
    e.preventDefault();

    // Collect the details of the chat from our UI
    var text = $( "#chatBox" ).val(),
        from = $( "#fromBox" ).val(),
        to = $( "#toBox" ).val();

    // Publish data from the chat to the newMessage topic
    mediator.publish( "newMessage" , { message: text, from: from, to: to } );
});

// Append new messages as they come through
function displayChat( data ) {
    var date = new Date(),
        msg = data.from + " said \"" + data.message + "\" to " + data.to;

    $( "#chatResult" )
        .prepend("" + msg + " (" + date.toLocaleTimeString() + ")");
}

// Log messages
function logChat( data ) {
    if ( window.console ) {
        console.log( data );
    }
}



// Subscribe to new chat messages being submitted
// via the mediator
mediator.subscribe( "newMessage", displayChat );
mediator.subscribe( "newMessage", logChat );


// The following will however only work with the more advanced implementation:

function amITalkingToMyself( data ) {
    return data.from === data.to;
}

function iAmClearlyCrazy( data ) {
    $( "#chatResult" ).prepend("" + data.from + " is talking to himself.");
}

 mediator.Subscribe( amITalkingToMyself, iAmClearlyCrazy );

Advantages and Disadvantages

The largest benefit of the Mediator pattern is that it reduces the communication channels needed between objects or components in a system from many to many to just many to one. Adding new publishers and subscribers is relatively easy due to the level of decoupling present.

Perhaps the biggest downside of using the pattern is that it can introduce a single point of failure. Placing a Mediator between modules can 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.

That said, it’s useful to remind ourselves that decoupled systems have a number of other benefits: if our modules communicated with each other directly, changes to modules (e.g., another module throwing an exception) could easily have a domino effect on the rest of our application. This problem is less of a concern with decoupled systems.

At the end of the day, tight coupling causes all kinds of headaches, and this is just another alternative solution, but one that can work very well if implemented correctly.

Mediator Versus Observer

Developers often wonder what the differences are between the Mediator pattern and the Observer pattern. Admittedly, there is a bit of overlap, but let’s refer back to the GoF for an explanation:

In the Observer pattern, there is no single object that encapsulates a constraint. Instead, the Observer and the Subject must cooperate to maintain the constraint. Communication patterns are determined by the way observers and subjects are interconnected: a single subject usually has many observers, and sometimes the observer of one subject is a subject of another observer.

Both Mediators and Observers promote loose coupling; however, the Mediator pattern achieves this by having objects communicate strictly through the Mediator. The Observer pattern creates observable objects that publish events of interest to objects that are subscribed to them.

JavaScript Prototype

The Prototype Pattern creates new objects, but rather than creating non-initialized objects it returns objects that are initialized with values it copied from a prototype – or example – object. The Prototype pattern is also referred to as the Properties pattern.

Using Prototype

An example of where the Prototype pattern is useful is the initialization of business objects with values that match the default values in the database. The prototype object holds the default values that are copied over into a newly created business object.

Classical languages rarely use the Prototype pattern, but JavaScript being a prototypal language uses this pattern in the construction of new objects and their prototypes.

Participants

The objects participating in this pattern are:

  • Client — In example code: the run() function.
    • creates a new object by asking a prototype to clone itself
  • Prototype — In example code: CustomerPrototype
    • creates an interfaces to clone itself
  • Clones — In example code: Customer
    • the cloned objects that are being created

Example

In the example code we have a CustomerPrototype object that clones objects given a prototype object. Its constructor function accepts a prototype of type Customer. Calling the clone method will generate a new Customer object with its property values initialized with the prototype values.

This is the classical implementation of the Prototype pattern, but JavaScript can do this far more effectively using its built-in prototype facility.

function CustomerPrototype(proto) {
    this.proto = proto;

    this.clone = function () {
        var customer = new Customer();

        customer.first = proto.first;
        customer.last = proto.last;
        customer.status = proto.status;

        return customer;
    };
}

function Customer(first, last, status) {

    this.first = first;
    this.last = last;
    this.status = status;

    this.say = function () {
        console.log("name: " + this.first + " " + this.last +
            ", status: " + this.status);
    };
}

function run() {

    var proto = new Customer("n/a", "n/a", "pending");
    var prototype = new CustomerPrototype(proto);

    var customer = prototype.clone();
    customer.say();
}

One of the benefits of using the Prototype pattern is that we’ve working with the prototype strengths JavaScript has to offer natively rather than attempting to imitate features of other languages. let’s look at the pattern example.

var myCar = {
  name: 'bmw',
  drive: function() {
    console.log('I am driving!');
  },
  panic: function() {
    console.log('wait, how do you stop this thing?');
  }
};

//Usages:

var yourCar = Object.create(myCar);

console.log(yourCar.name); //'bmw'

The GoF refers to the Prototype pattern as one that creates objects based on a template of an existing object through cloning.

We can think of the Prototype pattern as being based on prototypal inheritance in which we create objects that act as prototypes for other objects. The prototype object itself is effectively used as a blueprint for each object the constructor creates. If the prototype of the constructor function used contains a property called name for example (as per the code sample that follows), then each object created by that same constructor will also have this same property.


Reviewing the definitions for this pattern in existing (non-JavaScript) literature, we may find references to classes once again. The reality is that prototypal inheritance avoids using classes altogether. There isn’t a “definition” object nor a core object in theory; we’re simply creating copies of existing functional objects.

One of the benefits of using the Prototype pattern is that we’re working with the prototypal strengths JavaScript has to offer natively rather than attempting to imitate features of other languages. With other design patterns, this isn’t always the case.

Not only is the pattern an easy way to implement inheritance, but it can come with a performance boost as well: when defining functions in an object, they’re all created by reference (so all child objects point to the same function), instead of creating their own individual copies.

For those interested, real prototypal inheritance, as defined in the ECMAScript 5 standard, requires the use of Object.create (which we previously looked at earlier in this section).

To review, Object.create creates an object that has a specified prototype and optionally contains specified properties as well (e.g., Object.create( prototype, optionalDescriptorObjects )).

We can see this demonstrated in the following example:
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 );

Object.create also allows us to easily implement advanced concepts such as differential inheritance in which objects are able to directly inherit from other objects. We saw earlier that Object.create allows us to initialize object properties using the second supplied argument. For example:

var vehicle = {
  getModel: function () {
    console.log( "The model of this vehicle is.." + this.model );
  }
};

var car = Object.create(vehicle, {

  "id": {
    value: MY_GLOBAL.nextId(),
    // writable:false, configurable:false by default
    enumerable: true 
  },

  "model": {
    value: "Ford",
    enumerable: true
  }

});

Here, the properties can be initialized on the second argument of Object.create using an object literal with a syntax similar to that used by the Object.defineProperties and Object.defineProperty methods that we looked at previously.

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.

If we wish to implement the Prototype pattern without directly using Object.create, we can simulate the pattern as per the above example as follows:

var vehiclePrototype = {

  init: function ( carModel ) {
    this.model = carModel;
  },

  getModel: function () {
    console.log( "The model of this vehicle is.." + this.model);
  }
};


function vehicle( model ) {

  function F() {};
  F.prototype = vehiclePrototype;

  var f = new F();

  f.init( model );
  return f;

}

var car = vehicle( "Ford Escort" );
car.getModel();

A final alternative implementation of the Prototype pattern could be the following:

var beget = (function () {

    function F() {}

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

One could reference this method from the vehicle function. Note, however that vehicle here is emulating a constructor, since the Prototype pattern does not include any notion of initialization beyond linking an object to a prototype.

JavaScript Factory Pattern

Factory Method creates new objects as instructed by the client. One way to create objects in JavaScript is by invoking a constructor function with the new operator. There are situations however, where the client does not, or should not, know which one of several candidate objects to instantiate. The Factory Method allows the client to delegate object creation while still retaining control over which type to instantiate.

Using Prototype

An example of where the Prototype pattern is useful is the initialization of business objects with values that match the default values in the database. The prototype object holds the default values that are copied over into a newly created business object.

Classical languages rarely use the Prototype pattern, but JavaScript being a prototypal language uses this pattern in the construction of new objects and their prototype.

Participants

The objects participating in this pattern are:

  • Creator — In example code: Factory
    • the ‘factory’ object that creates new products
    • implements ‘factoryMethod’ which returns newly created products
  • AbstractProduct — not used in JavaScript
    • declares an interface for products
  • ConcreteProduct — In example code: Employees
    • the product being created
    • all products support the same interface (properties and methods)
var Factory = function () {
    this.createEmployee = function (type) {
        var employee;

        if (type === "fulltime") {
            employee = new FullTime();
        } else if (type === "parttime") {
            employee = new PartTime();
        } else if (type === "temporary") {
            employee = new Temporary();
        } else if (type === "contractor") {
            employee = new Contractor();
        }

        employee.type = type;

        employee.say = function () {
            console.log(this.type + ": rate " + this.hourly + "/hour");
        }

        return employee;
    }
}

var FullTime = function () {
    this.hourly = "$12";
};

var PartTime = function () {
    this.hourly = "$11";
};

var Temporary = function () {
    this.hourly = "$10";
};

var Contractor = function () {
    this.hourly = "$15";
};

function run() {

    var employees = [];
    var factory = new Factory();

    employees.push(factory.createEmployee("fulltime"));
    employees.push(factory.createEmployee("parttime"));
    employees.push(factory.createEmployee("temporary"));
    employees.push(factory.createEmployee("contractor"));

    for (var i = 0, len = employees.length; i < len; i++) {
        employees[i].say();
    }
}

JavaScript Mixin Pattern

Mixins are classes that offer functionality that can be easily inherited by a sub-class or group of sub-classes for the purpose of the function reuse.

var Person = function(firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;
  this.gender = 'male';
};

var clark = new Person('Clark', 'kent');

var Superhero = function(firstName, lastName, powers) {
  Person.call(this.firstName, this.lastName);
  this.powers = powers;
};

SuperHero.prototype = Object.create(Person.prototype);
var superman = new Superhero('Clark', 'Kent', ['flight', 'heat-vision']);

console.log(superman); //output personal attributes as well as power

JavaScript Decorator Pattern

The Decorators are a structural design pattern that aim to promote code reuse. Similar to Mixins, they can be considered another viable alternative to object subclassing. Classically, Decorators offered that ability to add behavior to existing classes in a system dynamically.

The idea was the decoration itself wasn’t essential to the base functionality of the class. Let’s checkout how decorator work in JavaScript

function MacBook() {
  this.cost = function() {
    return 997;
  };
  this.screenSize = function() {
    return 11.6;
  };
}

// Decorator 1

function Memory(macbook) {
  var v = macbook.cost();
  macbook.cost = function() {
    return v + 75;
  };
}

// Decorator 2

function Engraving(macbook) {
  var v = macbook.cost();
  macbook.cost = function() {
    return v + 200;
  };
}

// Decorator 3

function Insurance(macbook) {
  var v = macbook.cost();
  macbook.cost = function() {
    return v + 250;
  };
}

var mb = new MacBook();

Memory(mb);
Engraving(mb);
Insurance(mb);

mb.cost(); // 1522

JavaScript Adapter Design Pattern

The Adapter pattern translates one interface (an object‘s properties and methods) to another. Adapters allows programming components to work together that otherwise wouldn&lstqup;t because of mismatched interfaces. The Adapter pattern is also referred to as the Wrapper Pattern.

Using Adapter

One scenario where Adapters are commonly used is when new components need to be integrated and work together with existing components in the application.

Another scenario is refactoring in which parts of the program are rewritten with an improved interface, but the old code still expects the original interface.

Example

The example code below shows an online shopping cart in which a shipping object is used to compute shipping costs. The old Shipping object is replaced by a new and improved Shipping object that is more secure and offers better prices.

The new object is named AdvancedShipping and has a very different interface which the client program does not expect. ShippingAdapter allows the client program to continue functioning without any API changes by mapping (adapting) the old Shipping interface to the new AdvancedShipping interface.

// old interface

function Shipping() {
    this.request = function (zipStart, zipEnd, weight) {
        // ...
        return "$49.75";
    }
}

// new interface

function AdvancedShipping() {
    this.login = function (credentials) { /* ... */ };
    this.setStart = function (start) { /* ... */ };
    this.setDestination = function (destination) { /* ... */ };
    this.calculate = function (weight) { return "$39.50"; };
}

// adapter interface

function ShippingAdapter(credentials) {
    var shipping = new AdvancedShipping();

    shipping.login(credentials);

    return {
        request: function (zipStart, zipEnd, weight) {
            shipping.setStart(zipStart);
            shipping.setDestination(zipEnd);
            return shipping.calculate(weight);
        }
    };
}

function run() {

    var shipping = new Shipping();
    var credentials = { token: "30a8-6ee1" };
    var adapter = new ShippingAdapter(credentials);

    // original shipping object and interface

    var cost = shipping.request("78701", "10010", "2 lbs");
    console.log("Old cost: " + cost);

    // new shipping object with adapted interface

    cost = adapter.request("78701", "10010", "2 lbs");

    console.log("New cost: " + cost);
}

References:

The Constructor Pattern

The Module Pattern

The Mediator Pattern

Top 10 JavaScript Patterns Every Developer Likes

The Prototype Pattern

JavaScript Prototype

JavaScript Factory Method

Leave a Comment

Your email address will not be published. Required fields are marked *