②结构型设计模式适配器模式

Posted 狼丶宇先森

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了②结构型设计模式适配器模式相关的知识,希望对你有一定的参考价值。

一、写在前面

适配器模式(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

更多信息请关注公众号: “笔优站长”

扫码关注“笔优站长”,支持站长

以上是关于②结构型设计模式适配器模式的主要内容,如果未能解决你的问题,请参考以下文章

从零开始学习Java设计模式 | 结构型模式篇:适配器模式

②结构型设计模式适配器模式

②结构型设计模式适配器模式

②结构型设计模式适配器模式

设计模式之适配器模式与外观模式

结构型模式-适配器模式