JavaScript Design Patterns: Bridge

In my last blog post article I discussed the Singleton Design Pattern and how it is used in JavaScript. This time around the Bridge design pattern is poking its head up and asking for a bit of attention, making it the second in the JavaScript Design Patterns series.

Every place I’ve read about the Bridge pattern likes to quote the Gang of Four directly in their description of what the Bridge pattern is, so I figure why not me too? The Bridge pattern should “decouple an abstraction from its implementation so that the two can vary independently.” Bridges are quite beneficial in event-driven applications, which are quite common in JavaScript. Considering that fact, it’s surprisingly one of the most underused design patterns.

Event Listeners Example

In the following examples, I’ll be using a bit of jQuery, so if you don’t know what a function does or how it works, you can look at their documentation.

Below you’ll see a small bit of code using an API method called getXById, which is badly implemented. We are using a click event to determine which element to pull the id from. The callback itself is getXById, which gets the id from the clicked element and uses AJAX to get X from the server using the Id it found.

getXById = function() {
    var id = this.id;
	
    $.ajax({
        url:'/getx?id=' + id,
        success: function(response) {
            console.log(response);
        }
    });
}

$('someElement').bind('click', getXById);

This code isn’t all that bad if it’s only meant to be used that one specific way on the one specific page, but it’s (supposedly) part of an API, so this needs to be changed a lot. Let’s decouple getXById from the event listener and the implementation of what is done with the result:

getXById = function(id, callback) {
    $.ajax({
        url:'/getx?id=' + id,
        success: callback
    }
}

getXBridge = function() {
    var id = this.id;
    getXById(this.id, function() {
        console.log(response);
    });
}

$('someElement').bind('click', getXBridge);

Now the getXById can be used just about anywhere and you can do anything with X now.

Classical Example

What I mean by “classical” is two-fold: the example is more common to classic object-oriented programming languages and it is uses classes. Technically JavaScript doesn’t have classes but you mimic interfaces and use prototypes to mimic classes. Originally this example was in the book Head First Design Patterns, which uses Java in their example. However, this is one the minor patterns in the back of the book that didn’t actually have a code example, so I’m really just using the diagrams (except I recreated them because I’m awesome).

Our Starting Product

Original Remote Control DiagramWe start with the RemoteControl Interface. ToshibaRemote and SonyRemote both implement that interface to work with their respective televisions. With this code, you can call on(), off(), or setChannel() on any remote and even though all the TVs are different, it’ll work. What happens though, when you want to make improvements on the remotes? That’s where the Bridge pattern comes in:

Bridge Remote Control Diagram

Now, since the TVs adhere to an interface and all of the remotes adhere to another interface – actually just a class because it only needs the one implementation – we can create variations to either on through inheritance and still be compatible. Wanna see some code? I’ll show you the code for the new solution with the Bridge pattern, but I don’t think you need to see the code for the original. I really don’t think many of you need to see any code at all, but I’m sure there are those out there who’d like to see it anyway. We’re programmers, right? Show us the code!

var RemoteControl = function(tv) {
	this.tv = tv;
 
	this.on = function() {
		this.tv.on();
	};
 
	this.off = function() {
		this.tv.off();
	};
 
	this.setChannel = function(ch) {
		this.tv.tuneChannel(ch);
	};
};
 
/* Newer, Better Remote Control */
var PowerRemote = function(tv) {
	this.tv = tv;
	this.currChannel = 0;
 
	this.setChannel = function(ch) {
		this.currChannel = ch;
		this.tv.tuneChannel(ch);
	};
 
	this.nextChannel = function() {
		this.setChannel(this.currChannel + 1);
	};
 
	this.prevChannel = function() {
		this.setChannel(this.currChannel - 1);
	};
};
PowerRemote.prototype = new RemoteControl();
 
 
/** TV Interface
	Since there are no Interfaces in JavaScript I am just
	going to use comments to define what the implementors
	should implement
 
	function on
	function off
	function tuneChannel(channel)
*/
 
/* Sony TV */
var SonyTV = function() {
	this.on = function() {
		console.log('Sony TV is on');
	};
 
	this.off = function() {
		console.log('Sony TV is off');
	};
 
	this.tuneChannel = function(ch) {
		console.log('Sony TV tuned to channel ' + ch);
	};
}
 
/* Toshiba TV */
var ToshibaTV = function() {
	this.on = function() {
		console.log('Welcome to Toshiba entertainment');
	};
 
	this.off = function() {
		console.log('Goodbye Toshiba user');
	};
 
	this.tuneChannel = function(ch) {
		console.log('Channel ' + ch + ' is set on your Toshiba television');
	};
}
 
/* Let's see it in action */
var sony = new SonyTV(),
	toshiba = new ToshibaTV(),
	std_remote = new RemoteControl(sony),
	pwr_remote = new PowerRemote(toshiba);
 
std_remote.on();            // prints "Sony TV is on"
std_remote.setChannel(55);  // prints "Sony TV tuned to channel 55"
std_remote.setChannel(20);  // prints "Sony TV tuned to channel 20"
std_remote.off();           // prints "Sony TV is off"
 
pwr_remote.on();            // prints "Welcome to Toshiba entertainment"
pwr_remote.setChannel(55);  // prints "Channel 55 is set on your Toshiba television"
pwr_remote.nextChannel();   // prints "Channel 56 is set on your Toshiba television"
pwr_remote.prevChannel();   // prints "Channel 55 is set on your Toshiba television"
pwr_remote.off();           // prints "Goodbye Toshiba user"

Well, that just about wraps things up for the Bridge pattern in JavaScript. If you haven’t yet, make sure you go back and read about the Singleton Pattern. Also keep an eye out for the next article in this series: the Composite Pattern. If you thought this was helpful or you just plain liked the article, please spread the word using the social sharing buttons below the post. Thanks!

JavaScript Design Patterns series:

About the Author

Author: Joe Zim

Joe Zim

Joe Zimmerman has been doing web development ever since he found an HTML book on his dad's shelf when he was 12. Since then, JavaScript has grown in popularity and he has become passionate about it. He also loves to teach others though his blog and other popular blogs. When he's not writing code, he's spending time with his wife and children and leading them in God's Word.