【D1n910】《JavaScript 设计模式》第10章
正常操作,正常分析,大家好,我是D1n910。
今天继续来学习 《JavaScript 设计模式》的第三篇 结构型设计模式
这是一个连续的读书笔记,所以如果你之前的内容没有看的话,可以去看看。







这里再次感谢 《Javascript 设计模式》及其作者 张荣铭,专栏内容是在它的基础上生成的。
其实学到现在,会发现自己已经用到过这里面很多种设计模式了,这些都是上学上课、平时学习以及看之前大佬的代码耳濡目染的。
所以会有比较多的熟悉感,大家看到对应的模式的话,可以多思考一下平常自己是怎么用的,具体场景是怎么使用的。

第三篇 结构型设计模式
结构型设计模式关注于如何将类或者对象组合成更大、更复杂的结构,以简化设计。
第 10 章 水管弯弯 —— 适配器模式(P73)
适配器模式(Adapter):将一个类(对象)的接口(方法或者属性)转换成另一个接口,以满足用户需求,使类(对象)之间的接口的不兼容问题通过适配器得以解决。
(听起来有点像外观模式)
10.1、引入 JQuery(P73)
公司里有自己使用的内部框架 A,想要引入鼎鼎有名的框架 JQuery。
考虑之前用 A 写的代码是不是要重新用 JQuery 写一遍,比如:
A(function () {
A('button').on('click', function(e) {
// do something……
});
})
其实只需要写适配器就行。
10.2、生活中的适配器(P73)
以充电器为例子,不同地区的电压不同,所以通用的充电插头也不同,插座的插孔数也不同,地区A的两孔充电插头想要使用地区B的三孔插座,会用到适配器转换插座。
这里的适配器也是同样的道理。
10.3、JQuery 适配器(P74)
比如上面的框架 A 的公司框架,因为用法太像 Jquery 了,所以可以直接这么适配好。
window.A = A = Jquery
10.4、适配异形框架(P74)
在这里适配的概念就是把我们的代码里的内容转成我们要用到的框架的。
比如假如 A 框架没有和 Jquery 使用方式一致,而是像下面这样的内容。
var A = A || {};
A.g = function(id) {
return typeof id === 'string' ? document.getElementById(id) : id
}
// 为元素绑定事件(外观模式)
A.on = function(id, type, fn) {
var dom = this.g(id)
// 对于支持 DOM2 级事件处理程序 addEventListener 方法的浏览器
if (dom.addEventListener) {
dom.addEventListener(type, fn, false);
// 对于不支持 addEventListener 方法但支持 attachEvent 方法的浏览器
} else if (dom.attachEvent) {
dom.attachEvent('on' + type, fn);
} else {
dom['on'+ type] = fn
}
}
// 用法
A.on(window, 'load', function () {
A.on('mybutton', 'click', function () {})
})
那么改成 Jquery,就是原来的用法还是照样用,但是方法本身改成 Jquery 了。
A.g = function(id) {
return typeof id === 'string' ? $('#' + id) : $(id);
}
A.on = function(id, type, fn) {
var dom = this.g(id)
dom.on(type, fn)
}
这样我们这种异形的情况下的适配器就写好了。
所以不是到了万不得已的情况下,我们就不要引入不太相似的框架。这样方便适配。
10.5、参数适配器(P75)
适配器还有很多别的用途,比如我们原来的方法可能是这么写的。
function dosomething(id, name, age, time, like, weiboId, bilibiliId, baiduId) {
// do something
}
使用这个方法我们要传入大量的参数时还要记住参数的前后顺序,是比较麻烦的,我们可以改成对象传参的使用的方式。
function dosomethingAdapter(obj) {
dosomething(obj.id, obj.name, obj.age, obj.time, obj.like, obj.weiboId, obj.bilibiliId, obj.baiduId);
}
当然了,我们也可以适配一下需要默认值的情况。(当然了,当然了,新的 ES6 有更好的方式)
function dosomethingAdapter(obj) {
obj = obj || {}
var defaultObj = {
id: '',
name: '',
age: '',
time: '',
like: '',
weiboId: '',
bilibiliId: '',
baiduId: ''
}
for (var i in defaultObj) {
obj[i] = obj[i] || defaultObj[i]
}
dosomething(obj.id, obj.name, obj.age, obj.time, obj.like, obj.weiboId, obj.bilibiliId, obj.baiduId);
}
很多插件对于参数配置都是这么做的。
10.6、数据适配(P76)
我们也可以对于数据做专门的适配器。
比如像下面这一组数据
var arr = ['JavaScript', 'book', '前端编程语言', '8月1日']
这种数据结构语义不好,我们就可以像下面这样得到可用性强的对象形式。
function arrToObjAdapter(arr) {
return {
name: arr[0],
type: arr[1],
title: arr[2],
data: arr[3]
}
}
arrToObjAdapter(arr); // {name: "JavaScript", type: "book", title: "前端编程语言", data: "8月1日"}
(感觉emmm,好像过于简单了,不过养成这种弄成对象的结构总是好的)
10.7、服务器端数据适配(P77)
这个就更令人xxdd了。
实际上就是后端同学非要改接口返回的数据格式,嵌套格式怎么办,最好就不要跟着把我们原来的方法也进行修改了。而应该通过一个适配器转换成原函数要的数据。
本章节 End
学习进度(10/40)
本来想看看第11章的代理模式是啥的,觉得好像很简单的样子,确实很简单,但是作者这描述出来的内容,让我理解不能,所以下面会跳过第11章,等我睡一觉清醒后再看一遍,看看能不能看懂!
D1n910 于 2020年02月19日20:20 在 福永