You are previewing Learning JavaScript Design Patterns.

Learning JavaScript Design Patterns

Cover of Learning JavaScript Design Patterns by Addy Osmani Published by O'Reilly Media, Inc.
  1. Learning JavaScript Design Patterns
  2. SPECIAL OFFER: Upgrade this ebook with O’Reilly
  3. Preface
    1. Target Audience
    2. Credits
    3. Reading
    4. Conventions Used in This Book
    5. Using Code Examples
    6. Safari® Books Online
    7. How to Contact Us
    8. Acknowledgments
  4. 1. Introduction
  5. 2. What Is a Pattern?
    1. We Already Use Patterns Every Day
  6. 3. “Pattern”-ity Testing, Proto-Patterns, and the Rule of Three
  7. 4. The Structure of a Design Pattern
  8. 5. Writing Design Patterns
  9. 6. Anti-Patterns
  10. 7. Categories of Design Patterns
    1. Creational Design Patterns
    2. Structural Design Patterns
    3. Behavioral Design Patterns
  11. 8. Design Pattern Categorization
    1. A Brief Note on Classes
  12. 9. JavaScript Design Patterns
    1. The Constructor Pattern
      1. Object Creation
      2. Basic Constructors
      3. Constructors with Prototypes
    2. The Module Pattern
      1. Object Literals
      2. The Module Pattern
      3. Module Pattern Variations
    3. The Revealing Module Pattern
      1. Advantages
      2. Disadvantages
    4. The Singleton Pattern
    5. The Observer Pattern
      1. Differences Between the Observer and Publish/Subscribe Pattern
      2. Advantages
      3. Disadvantages
      4. Publish/Subscribe Implementations
    6. The Mediator Pattern
      1. Basic Implementation
      2. Advanced Implementation
      3. Example
      4. Advantages and Disadvantages
      5. Mediator Versus Observer
      6. Mediator Versus Facade
    7. The Prototype Pattern
    8. The Command Pattern
    9. The Facade Pattern
      1. Notes on Abstraction
    10. The Factory Pattern
      1. When to Use the Factory Pattern
      2. When Not to Use the Factory Pattern
      3. Abstract Factories
    11. The Mixin Pattern
    12. Subclassing
    13. Mixins
      1. Advantages and Disadvantages
    14. The Decorator Pattern
    15. Pseudoclassical Decorators
      1. Interfaces
      2. Abstract Decorators
    16. Decorators with jQuery
    17. Advantages and Disadvantages
    18. Flyweight
      1. Using Flyweights
      2. Flyweights and Sharing Data
      3. Implementing Classical Flyweights
      4. Converting Code to Use the Flyweight Pattern
      5. A Basic Factory
      6. Managing the Extrinsic States
      7. The Flyweight Pattern and the DOM
  13. 10. JavaScript MV* Patterns
    1. MVC
      1. Smalltalk-80 MVC
    2. MVC for JavaScript Developers
      1. Models
      3. Controllers
      4. Controllers in Another Library (Spine.js) Versus Backbone.js
    3. What Does MVC Give Us?
    4. Smalltalk-80 MVC in JavaScript
      1. Delving Deeper
      2. Summary
    5. MVP
      1. Models, Views, and Presenters
      2. MVP or MVC?
      3. MVC, MVP, and Backbone.js
    6. MVVM
      1. History
      2. Model
      3. View
      4. ViewModel
      5. Recap: The View and the ViewModel
      6. Recap: The ViewModel and the Model
    7. Pros and Cons
      1. Advantages
      2. Disadvantages
    8. MVVM with Looser Data Bindings
    9. MVC Versus MVP Versus MVVM
    10. Backbone.js Versus KnockoutJS
  14. 11. Modern Modular JavaScript Design Patterns
    1. A Note on Script Loaders
    2. AMD
      1. Getting Started with Modules
      2. AMD Modules with Dojo
      3. AMD Module Design Patterns (Dojo)
      4. AMD Modules with jQuery
      5. AMD Conclusions
    3. CommonJS
      1. Getting Started
      2. Consuming Multiple Dependencies
      3. Loaders and Frameworks that Support CommonJS
      4. Is CommonJS Suitable for the Browser?
      5. Related Reading
    4. AMD and CommonJS: Competing, but Equally Valid Standards
      1. UMD: AMD and CommonJS-Compatible Modules for Plug-ins
    5. ES Harmony
      1. Modules with Imports and Exports
      2. Modules Loaded from Remote Sources
      3. Module Loader API
      4. CommonJS-like Modules for the Server
      5. Classes with Constructors, Getters, and Setters
      6. ES Harmony Conclusions
      7. Related Reading
    6. Conclusions
  15. 12. Design Patterns in jQuery
    1. The Composite Pattern
    2. The Adapter Pattern
    3. The Facade Pattern
    4. The Observer Pattern
    5. The Iterator Pattern
    6. Lazy Initialization
    7. The Proxy Pattern
    8. The Builder Pattern
  16. 13. jQuery Plug-in Design Patterns
    1. Patterns
    2. A Lightweight Start Pattern
      1. Further Reading
    3. Complete Widget Factory Pattern
      1. Further Reading
    4. Nested Namespacing Plug-in Pattern
      1. Further Reading
    5. Custom Events Plug-in Pattern (with the Widget Factory)
      1. Further Reading
    6. Prototypal Inheritance with the DOM-to-Object Bridge Pattern
      1. Further Reading
    7. jQuery UI Widget Factory Bridge Pattern
      1. Further Reading
    8. jQuery Mobile Widgets with the Widget Factory
    9. RequireJS and the jQuery UI Widget Factory
      1. Usage
      2. Further Reading
    10. Globally and Per-Call Overridable Options (Best Options Pattern)
      1. Further Reading
    11. A Highly Configurable and Mutable Plug-in Pattern
      1. Further Reading
    12. What Makes a Good Plug-in Beyond Patterns?
      1. Quality
      2. Code Style
      3. Compatibility
      4. Reliability
      5. Performance
      6. Documentation
      7. Likelihood of maintenance
    13. Conclusions
    14. Namespacing Patterns
    15. Namespacing Fundamentals
      1. Single Global Variables
      2. Prefix Namespacing
      3. Object Literal Notation
      4. Nested Namespacing
      5. Immediately Invoked Function Expressions (IIFE)s
      6. Namespace Injection
    16. Advanced Namespacing Patterns
      1. Automating Nested Namespacing
      2. Dependency Declaration Pattern
      3. Deep Object Extension
      4. Recommendation
  17. 14. Conclusions
  18. A. References
  19. Index
  20. About the Author
  21. Colophon
  22. SPECIAL OFFER: Upgrade this ebook with O’Reilly
  23. Copyright
O'Reilly logo

The 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. A centralized controller is key to the success of this system, and that’s really the role that the Mediator plays in software design (Figure 9-5).

Mediator pattern

Figure 9-5. Mediator pattern

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


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

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


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:

<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 action="submit">Chat</button>

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

Here is the JavaScript code:

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

    // 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 " +;

    $( "#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 ===;

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.

Mediator Versus Facade

We will be covering the Facade pattern shortly, but for reference purposes, some developers may also wonder whether there are similarities between the Mediator and Facade patterns. They do both abstract the functionality of existing modules, but there are some subtle differences.

The Mediator pattern centralizes communication between modules where it’s explicitly referenced by these modules. In a sense, this is multidirectional. The Facade pattern, on the other hand, just defines a simpler interface to a module or system but doesn’t add any additional functionality. Other modules in the system aren’t directly aware of the concept of a facade and could be considered unidirectional.

[3] Thanks to Jack for his excellent code comments which assisted with this section.

The best content for your career. Discover unlimited learning on demand for around $1/day.