Adapter

Matches interfaces of different objects.

jQuery uses the Adapter pattern to support backward compatibility to older APIs.



Overview


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

In jQuery you attach an event handler to click, mouseover, keypress, focus, resize, scroll and other events like this:

$("#div").click(function() { alert("hello"); };

$("#name").focus(function() { alert("name please"); };

These are shorthand methods for the more generic bind method, which is used like this:

$("#div").bind("click", function() { alert("hello"); };

$("#name").bind("focus", function() { alert("name please"); };

In older versions of jQuery all shorthand methods were mapped to bind or trigger methods:

function click (fn) {
    return fn ? this.bind(name, fn) : this.trigger(name);
}

This code shows that if an event handler (fn) is provided it is bound, but if none is provided it triggers the specific event. This mapping of shortcut methods to the more generic bind method is the Adapter Pattern in action.

This functionality continuous to be supported, but in recent versions two new methods on an off were introduced. They attach and detach event handlers respectively. The two methods unify all good practices of event handling and allow you to write nice tidy code. It is used just like the bind method above:

$("#div").on("click", function() { alert("hello"); };

$("#div").on("focus", function() { alert("name please"); };
    

Again the Adapter Pattern translates the call from bind to on. Here is a glimpse into jQuery's source which shows how this is done:

jQuery.each( (
  "blur focus focusin focusout load resize scroll unload click dblclick " +
  "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
  "change select submit keydown keypress keyup error contextmenu")
   .split(" "), 
    function( i, name ) {
        // Handle event binding
        jQuery.fn[ name ] = function( data, fn ) {
            if ( fn == null ) {                   // argument switching
                fn = data;
                data = null;
            }

            return arguments.length > 0 ?
                this.on( name, null, data, fn ) :
                this.trigger( name );
       };
});

This code iterates over an array of shorthand method names and adds each one to jQuery.fn. They are mapped to either the on method or the trigger method depending on the arguments passed (trigger, as the name implies, triggers the event). Notice also that argument switching (function overload idiom) is used in these convenience methods.

Here is another jQuery Adapter in action. This time with the important ajax method:

ajax: function( url, options ) {
    // If url is an object, simulate pre-1.5 signature
    if ( typeof url === "object" ) {
        options = url;
        url = undefined;
    }
    // ...
}

This method is adapted to support/simulate older versions of the API. It does this through argument switching which allows it to support the current API and the older API. The fact that this is all handled in a single function is rather unusual.



  Façade