Adapter Design Pattern

Convert the interface of a class into another interface clients expect.   Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.  
Gang of Four, Design Patterns
What Is It?

The Adapter pattern is strictly about conversion.   It is sometimes called a wrapper because an adapter class wraps the implementation of another class in the desired interface.   Of course, any new method in subclasses must be changed, added or extended within the Adapter...but so what.  


STARTING POINT: LOGGER "FACTORY"

The thing to notice here is the "dependency" on the method Log.   And yes, I understand the dependency is on the entire console object as-a-whole...so I don't need to see emails on this.

// SIMPLE LOGGER FACTORY
var LoggerFactory = {
    getLogger: function() {
        return window.console;
    },
    ...
};
 
// USAGE - Notice dependency on the method 'log'
var logger = LoggerFactory.getLogger();
logger.log("something to log");
                            

...I really gotta start using something other than Loggers in explanations (yawn!).


START of PROBLEM: Shiney New Bauble Arrives

Suddenly, a new shiny AjaxyLogger comes along & it is awesome: can't wait to use it.   But wait...look at it's interface!   It looks nothing like what I am currently using.   How am I going to use it?  

// SHINY NEW LOGGER COMES ALONG - But its different?
// USAGE - Notice dependency on the method 'sendLog'
var AjaxLogger = {
    sendLog: function(arg) {
        var data = this.urlEncode(arg);
         
        jQuery.ajax({
            url: "http://example.com/log",
            data: data
        });
    },
     
    urlEncode: function(arg) {
        ...
        return encodedData;
    },
    ...
};
                            

ANSWER: The Adapter (of course)

The Adapter is perfect for this scenario!   Just write an adapter to "wrap" your new AjaxLogger & make the wrapper conform to the interface requirements of the original logger.  

// PROBLEM: We dont have time to rewrite everything that uses LOGGER
//  ANSWER: AjaxLoggerAdapter to the rescue!
var AjaxLoggerAdapter = {
    log: function(arg) {
        AjaxLogger.sendLog(arg);
    }
};
 
// UPDATE THE FACTORY
// NOTICE - Usage of the 'log' method doesnt change (ta da!)
var LoggerFactory = {
    getLogger: function() {
        // just gotta change what's returned here
        return AjaxLoggerAdapter;
    },
    ...
};
                            

ON A SIDE NOTE

This scenario is exactly why I always tell people "wrapping and/or injecting" utilities is a best practice.   Doing this change would be impossible if you had to trundle through a large code-base.

Structural

Copyright © 2015 All Rights Reserved