js设计模式-适配器模式

适配器模式介绍

定义:适配器模式(Adapter)是将一个类(对象)的接口(方法或属性)转化成客户希望的另外一个接口(方法或属性),
适配器模式使得原本由于接口不兼容而不能一起工作的那些类(对象)可以一些工作。速成包装器(wrapper)。
使用场景:适配器模式往往用于适配两个接口不兼容的问题,在js中应用更为广泛,比如适配两个代码库、适配前后端数据。

因此应对这种场景,我们可以很快地想到可以用适配器模式来解决这个问题。

参数适配

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
//比如某个方法中需要传入多个参数

function doSomething(name,title,age,type,color,size){}

//记住这些参数顺序很难,所以我们经常是以一个参数的形式传进去
var obj = {
name: name,
title:title,
age:age,
type:type
}

function doSomething(obj){}

//但是有的时候传入参数不完整或者默认的情况,这个时候我们需要适配器适配传入的参数对象
function doSomething(obj){
var _adapter={
name:'设计模式'
title:'js',
age:2,
color:'red'
}
for(var i in _adapter){
return _adapter[i]=obj[i]||_adapter[i];
}
}




// 定义一个接口方法,传3个参数
function interfaceMethod(a1,a2,a3){
// 随便写个弹出框
alert(a1+a2+a3+'');
}

// 定义一个对象
var o = {
s1:'飞狐就是帅',
s2:',撸壕,',
s3:'大卫'
}

// 适配器函数,把传递的对象参数转换为interfaceMethod函数需要的形式
function adapter(o){
interfaceMethod(o.s1,o.s2,o.s3);
}
adapter(o); //飞狐就是帅,撸壕,大卫

数据适配

往往后端返回的数据格式不是我们想要的格式,通常我们会将数据适配成正确的格式,然后进行操作。例如请求的数据是数组,通过适配模式数据格式变对象

1
var arr = ['javascript','book','8月1号','设计模式']

数据格式每个成员语义不同,通常转换成对象形式,

1
2
3
4
5
6
7
8
function adapterData(arr){
return {
name:arr[0],
type:arr[1],
time:arr[2],
title:arr[3]
}
}

进而将数组转成了下面的格式:

1
2
3
4
5
6
7
8
var obj={
name:'',
type:'',
time:'',
title:'',
}
var data = adapterData(arr);
//{name: "javascript", type: "book", time: "8月1号", title: "设计模式"}

适配不同库

Prototype库的$函数到YUI的get方法的转换,网上最多的一个适配器模式的讲解,看例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
// 模拟Prototype,根据id获取DOM元素,不需要传递任何的形参,一个id写一个参数,多个id多个参数
function $(){
// 定义一个结果数组
var elements = [];
// 遍历传入参数
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;
// 否则加入数组
elements.push(element);
}
// 返回数组
return elements;
}

// 模拟雅虎
var YAHOO = {};
// YUI中get只接受一个参数,字符串或数组
YAHOO.get = function(el){
// 判断是否为字符串
if(typeof el == 'string'){
return document.getElementById(el);
};
// 判断是否为数组
if(el instanceof Array){
var elements = [] ;
for(var i=0;i<el.length;i++){
elements[elements.length] = YAHOO.get(el[i]);
}
return elements;
}
// 如果都不是,直接返回
if(el){
return el;
}
// 否则返回null
return null;
}

// YUI适配器
YAHOO.get = YUIToPrototypeAdapter;
// 适配器函数
function YUIToPrototypeAdapter(){
// 对于YUI开发人员来说 永远传递一个参数
if(arguments.length == 1){
var el = arguments[0];
// 这里判断是否为数组,如果是直接返回,否则包装成数组返回,如:"a",包装后["a"]
return $.apply(window,el instanceof Array?el:[el]);
} else {
// 如果是多个参数的情况,这里只能用apply,不能用call
return $.apply(window,arguments);
}
}

// 测试数组的情况
var arr = YAHOO.get(['fox1','fox2','fox3']);
alert(arr);
// 测试多个参数的情况
var arr = YAHOO.get('fox1','fox2','fox3');
alert(arr);

Buy me a cup of coffee,thanks!