概述
一、写在前面
适配器模式(Adapter):将一个类(对象)的接口(方法或者属性)转化成另外一个接口,以满足用户需求,使类(对象)之间接口的不兼容问题通过适配器得以解决。
上述的简介,你能想到这个模式是怎么样的吗?
本系列文章上次更新是一个月前了,很抱歉,最近项目太忙了,我已经加了一个月的班了,月平均工时12.1个小时。回到家的时候基本上都是23点左右了,实在太累了。
关注公众号“笔优站长”可阅读全部文章哟。
二、场景实例 —— JQuery
生活中的适配器
可能直接说适配器,还是有朋友会出现一脸懵逼的样子,那就举个简单的例子。
生活中这种模式也很常见,你看公司的水房的两根垂直相交的水管连接处的直角弯管了么?它就是一个适配器,它使得两个不同方向的水管可以疏通流水。再比如我们三角插头手机充电器对于两项插头是不能用的,此时我们就需要一个三项转两项插头电源适配器等等,这些都是适配器。
JQuery适配器
jQuery曾经也是一个时代的王者,但是随着单页应用的发展,以及数据驱动的出现。直接操作dom的方式逐渐就没落了,例如现在的Vue、React等。
那么曾经的这个王者还有值得我们学习的地方吗?答案是肯定的,虽然目前直接操作dom的方式没那么流行了。但是jQuery的封装以及设计模式上,还是有值得我们去学习的地方。
但是这里并不是重点说jQuery,请看下面的例子:
假如公司里有个内部框架 A 框架
A(function(){
A('button').on('click',function(){
//TODO...
});
});
这个框架和jQuery十分相似,只不过功能方法没有jQuery多,命名方式是A,jQuery的方法是jQuery或者$,你看公司的A框架代码书写格式是不是与jQuery代码书写格式很像,所以你需要在加载完jQuery框架后写一个适配器。将我们已有的功能适配到jQuery。比如代码中有两个
件,一个页面加载事件,一个点击事件。不过这两个事件与jQuery中的写法很像,所以这就不用做多少改动了。我们的适配器主要的任务是适配两种代码库中不兼容的代码。那么首其冲的就是全局对象A与jQuery了,所以你可以像下面这样轻松实现。
window.A = A = jQuery;
做完这个,你刷新页面看看是不是运行良好?
适配异类框架
类似于jQuery的轻量级框架要做适配就可以直接进行覆盖,那么假如两个相似程度属于“远亲”的这种又怎么处理呢?
举个例子:
//定义A框架
var A = A || {};
//通过ID获取元素
A.g = function(id){
return document.getElementById(id);
}
//为元素绑定事件
A.on = function(id,type,fn)(
//如果传递参数是字符串则以id处理,否则以元素对象处理
var dom=typeof id ==='string'?this.g(id):id;
//标准DOM2级添加事件方式
if(dom.addEventListener)(
dom.addEventListener(type,fn,false);
//IE DOM2级添加事件方式
}else if(dom.attachEvent){
dom.attachEvent('on' + type,fn);
//简易添加事件方式
}else{
dom['on'+ type] = fn;
}
}
那么要完成上面的需求我们可以这样做。
//窗口加载完成事件
A.on(window,'load',function()(
//按钮点击事件
A.on('mybutton','click',function(){
// do something
})
})
那么我想引入jQuery来换原有的A库,你知道该如何做么?
思路: 首先g方法是通过id获取元素,所以通过$(jQuery的简写名称)方法获取jQuery对象然后通过get获取第一个成员即可,不过on方法有些复杂,我们不能直接替换,因为jQuery和我们的A库在通过id获取元素时是有区别的,jQuery的id前面要加#。所以异类框架的适配器应该是这样的吧。
A.g= function(id){
//通过jQuery获取jQuery对象,然后返回第一个成员
return.$(id).get(0);
}
A.on = function(id,type,fn){
//如果传递参数是字符串则以id处理,否则以元素对象处理
var dom = typeof id ==='string'?$('#'+ id):$(id);dom.on(type,fn);
}
通过适配器我们发现如果两种框架的‘血缘’比较相近,那么我们适配起来是比较容易的,如果‘血缘’相差甚远我们的适配器写起来要复杂得多,因此要记住,日后非到万不得已情况下,尽量引入相似框架。
参数适配器
/**
* obj.name : name
* obj.title : title
* obj.age : age
* obj.color : color
* obj.size : size
* obj.prize : prize
*/
function doSomeThing(obj){}
上面有这样一个方法,然而当调用它的时候又不知道传递的参数是否完整,如有一些必须参数没有传入,一些参数是有默认值的等等,此时我们通常的做法是用适配器来适配传入的这个参数对象。如下所示:
function dosomeThing(obj)(
var _adapter = {
name:'雨夜清荷',
title:'设计模式,
age:24,
color:'pink',
size:100,
prize:50
}
for (var i in _adapter){
adapter[i] = obj[i] || adapter[i];
}
//或者extend(_adapter,obj)注:此时可能会多添加属性
// do things
}
其实这种方式很常见,很多插件对于参数配置都是这么做的。
留下两个问题:
数据适配
???
服务端数据适配
???
这两个和前面说的都大同小异,有思路就能解决。
三、总结
传统设计模式中,适配器模式往往是适配两个类接口不兼容的问题,然而在JavaScript中,适配器的应用范围更广,比如适配两个代码库,适配前后端数据,等等。
JavaScript中的适配器的应用,更多应用在对象之间,为了使对象可用,通常我们会将对象拆分并重新包装,这样我们就要了解适配对象的内部结构,这也是与外观模式的区别所在,当然适配器模式同样解决了对象之间的耦合度。包装的适配器代码增加了一些资源开销,当然这是微乎其微的。
下章剧透 :跨域访问的问题,该如何解决呢?
六、写在后面
上面就是结构型设计模式中的——适配器模式的全部内容了,你学废了吗?
有问题请留言或者@博主,谢谢支持o( ̄︶ ̄)o~
感谢您的阅读,如果此文章或项目对您有帮助,请扫个二维码点个关注吧,若可以的话再给个一键三连吧!
公众号阅读的朋友可以点一下右下角的在看和分享哦。
GitHub有开源项目,需要的小伙伴可以顺手star一下!
GitHub: https://github.com/langyuxiansheng
更多信息请关注公众号: “笔优站长”
最后
以上就是飞快黑夜为你收集整理的②【结构型设计模式】适配器模式的全部内容,希望文章能够帮你解决②【结构型设计模式】适配器模式所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复