The Mediator Pattern

The American Heritage dictionary defines the word mediator as “one that mediates, especially one that reconciles differences between disputants.” In this manner, the mediator pattern usually implements a single object that becomes a shared resource through all of the different pieces of an application. It’s a higher-level version of pub/sub in that it’s commonly used to communicate across the different features of an application in contrast to being used within one feature to communicate with all of the individual pieces of that same feature.

“Understanding the similarities and differences between an event aggregator and mediator is important for semantic reasons.”
- Derick Bailey

This article is part of a series called JavaScript Design Patterns.

Advantages

Disadvantages

Example

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
var Mediator = ( function( window, undefined ) {
 
function Mediator() {
this._topics = {};
}
 
Mediator.prototype.subscribe = function mediatorSubscribe( topic, callback ) {
if( ! this._topics.hasOwnProperty( topic ) ) {
this._topics[ topic ] = [];
}
 
this._topics[ topic ].push( callback );
return true;
};
 
Mediator.prototype.unsubscribe = function mediatorUnsubscrive( topic, callback ) {
if( ! this._topics.hasOwnProperty( topic ) ) {
return false;
}
 
for( var i = 0, len = this._topics[ topic ].length; i < len; i++ ) {
if( this._topics[ topic ][ i ] === callback ) {
this._topics[ topic ].splice( i, 1 );
return true;
}
}
 
return false;
};
 
Mediator.prototype.publish = function mediatorPublish() {
var args = Array.prototype.slice.call( arguments );
var topic = args.shift();
 
if( ! this._topics.hasOwnProperty( topic ) ) {
return false;
}
 
for( var i = 0, len = this._topics[ topic ].length; i < len; i++ ) {
this._topics[ topic ][ i ].apply( undefined, args );
}
return true;
};
 
return Mediator;
 
} )( window );
 
// example subscriber function
var Subscriber = function ExampleSubscriber( myVariable ) {
console.log( myVariable );
};
 
// example usages
var myMediator = new Mediator();
myMediator.subscribe( 'some event', Subscriber );
myMediator.publish( 'some event', 'foo bar' ); // console logs "foo bar"

Additional Resources

http://lostechies.com/derickbailey/2013/03/18/event-aggregator-andorvs-mediator-a-tale-of-two-patterns/
http://www.dofactory.com/javascript-mediator-pattern.aspx
http://addyosmani.com/resources/essentialjsdesignpatterns/book/#mediatorpatternjavascript

Other Common JS Patterns

The Module Pattern
The Revealing Module Pattern
The Singleton Pattern
The Observer Pattern
The Mediator Pattern
The Prototype Pattern
The Facade Pattern
The Factory Pattern

6 responses!

Rhys Brett-Bowen said: (8 months ago) Reply

I built a mediator called Nerve here: https://github.com/rhysbrettbowen/Nerve – it allows wildcards when listening for messages. Originally build for Google Closure but it was updated to work with underscore.js as a dependency.

Neville Franks said: (8 months ago) Reply

I’ve personally found most articles on the mediator pattern to be somewhat confusing as they appear to be nothing much more than typical pub/sub. And this is what I see with your code. For another example see Addy Osmani’s Mediator Pattern(2) article and this associated issue(3).

Jim Cowart’s “Client-side Messaging Essentials”(1) article mentions ‘code smell’ in the context of pub/sub, which I agree with. By ‘code smell’ he is referring to splattering pub/sub code throughout your modules, which detracts from the “loose coupling” that mediator should provide.

I’ve written a mediator that hides all pub/sub calls and lets you use various pub/sub libs. I hope to publish this on Github soon’ish.

  1. http://www.freshbrewedcodes.com/jimcowart/2013/02/07/client-side-messaging-essentials/
  2. http://addyosmani.com/largescalejavascript/#mediatorpattern
  3. https://github.com/addyosmani/essential-js-design-patterns/issues/41
    carldanley said: (8 months ago) Reply

    Can you elaborate a little more as to why this code is confusing? It’s a popular example found throughout the internet when directly referring to the mediator pattern. I’ve also found several resources which identify the pub/sub pattern as a “derivative” of the mediator pattern but same in concept.

    Both, the second and the third link you shared agree with the code example above; especially Addy’s as the code example is based on his book. As for Jim Cowart’s article, I found that it obfuscated the original point here. Consider the following:

    https://gist.github.com/carldanley/2eb86f8585aaf3f46148

    ComponentA and ComponentB aren’t aware of each other in any way. Can you explain to me what the problem with this code is? I’d like to also point out that both ComponentA & ComponentB manage their own subscriptions to each event and do not care what else is subscribed to those events; thus, encouraging decoupling.

    I’m interested to hear your thoughts and would love to see the mediator code you’ve written.

    Josh said: (3 months ago) Reply

    Why don’t you publish your mediator on Github?

Neville Franks said: (8 months ago) Reply

I wasn’t suggesting there is a problem with your code or even Addy’s. My problem is that I can’t see any difference between these and pub/sub and from what I can gleam the mediator pattern should deliver even looser coupling of components than pub/sub. The Gist and comments at https://github.com/addyosmani/essential-js-design-patterns/issues/41 by andrzejpolis states “They are identical. In fact they both look exactly like correct pub/sub pattern.” and then goes on to explain what he expects from a mediator, which I used to help form my mediator.

I was using a pub/sub implementation quite heavily in a app that I’m developing and then I came across a far better implementation that provided a capability that was of great interest. The problem was the api’s for these two lib’s were completely different and I would have had to do bulk changes to switch to the new one. I started doing some more research on “loose coupling”, came across mediator and thought this should abstract away the specific pub/sub implementation and make this and any future switch a lot easier. But then every article I found about mediator was just another pub/sub implementation, and of no help.

So then I sat down and wrote something I call a mediator which does abstract away the specific pub/sub implementation, allowing it to be changed in one module with minimal effort. I haven’t written a pub/sub and simply use the most appropriate third party implementation.

At the same time I wanted to (re)move all the event strings that pub/sub uses that were splattered throughout my code. I come from many years of C++ development and don’t like the idea of using strings to identify what is actually a function, especially when they are used all over the place. The “code smell” comment by Jim Cowart resonates with me here.

Whether my mediator is actually a mediator or not I don’t know, but it has met my objectives and has made my code less smelly. I’ll e-mail you a copy of the code and will be interested in your thoughts.

    Christian Andrade said: (3 months ago) Reply

    Hi Neville, I’m very interested to see your mediator, sounds really interesting, can you send a copy of the code ?

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>