JS设计模式——11.适配器模式

适配器模式概述

适配器模式可用来在现有接口和不兼容的类之间进行适配。使用这种模式的对象又叫包装器(wrapper)

适配器特点

从表面看,适配器模式很像门面模式。她们都要对别的对象进行包装并改变其呈现的接口。

二者的区别在于她们如何改变接口:

  • 门面元素展现的是一个简化的接口,她并不提供额外的选择,而且有时为了方便完成任务她还会做出一些假定。
  • 适配器则要把一个接口转换为另一个接口,她并不滤除某些能力,也不会简化接口。

假设有一个对象,还有一个以三个字符串为参数的函数:

var clientObject = {

    string1: 'foo',

    string1: 'bar',

    string1: 'baz'

};

function interfaceMethod(str1, str2, str3){

    console.log('ehhe');

}

为了把clientObject作为参数传递给interfaceMethod,需要用到适配器。如下:

function clientToInterfaceAdapter(o){//适配器

    interfaceMethod(o.string1, o.string2, o.string3);

}

示例:适配两个库

下面我们来实现从Prototype库的$函数到YUI的get方法的转换。这两个函数的功能比较相似,不过先看看她们在接口方面的差别:

function $(){

    var elments = new Array();

    for(var i=0; i<arguments.length; i++){

        var element = arguments[i];

        if(typeof element == 'string'){

            element = document.getElementById(element);

        }

        if(arguments.length == 1){

            return element;

        }

        elments.push(element);

    }

    return elements;

}

YAHOO.util.Dom.get = function(el){

    if(YAHOO.lang.isString(el)){

        return document.getElementById(el);

    }

    if(YAHOO.lang.isArray(el)){

        var c = [];

        for(var i= 0, len=el.length; i<len; i++){

            c[c.length] = YAHOO.util.Dom.get(el[i]);

        }

        return c;

    }

    if(el){

        return el;

    }

    return null;

}

二者的区别主要在于:get具有一个参数,这个参数可以是一个HTML元素、字符串或者由字符串或HTML元素组成的数组,与此不同,$函数没有正式列出参数,而是允许客户传入任意数目的参数,不管是字符串还是HTML元素都行。

如果要实现从$方法到get方法的转换(或者相反),那么用于这个用途的适配器会是什么样子呢?

function $2getAdapter(){

    return YAHOO.util.Dom.get(arguments);

}

function get2$Adapter(el){

    return $.apply(window, el instanceof Array ?el: [el]);

}

对于从Prototype改投YUI的人应该如下使用:

$ = $2getAdapter;

相反的如下使用:

YAHOO.util.Dom.get = get2$Adapter;

适配器模式的使用场合

适配器适用于客户系统期待的接口与现有API提供的接口不兼容这种场合。她只能用来协调语法上的差异问题。适配器所适配的两个方法执行的应该是类似的任务,否则她就解决不了问题。

适配器模式之利

适配器模式有利于避免大规模改写现有客户代码。

适配器模式之弊

如果现有API还未定形,或者新街口还未定形,那么适配器可能不会一直管用。

你可能感兴趣的:(适配器模式)