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还未定形,或者新街口还未定形,那么适配器可能不会一直管用。

原文地址:https://www.cnblogs.com/JChen666/p/3658551.html