适配器模式 (Adapter): 将一个类(对象) 的接口 (方法或属性) 转化成为另外一个接口,使类(对象)之间接口的不兼容问题通过适配器得以解决。
不知道大家有没有遇到过这种场景,期初一个项目没有引用 jQuery 这类 js,然后又觉得每次用 document 对象点出属性很麻烦,于是自己写了个全局的方法,来实现通过 id 的标识获取元素。
- function MyQuery(id) {
- return document.querySelector(id);
- }
在这个例子中,我们用 MyQuery 替代了 document.querySelector 方法,那么如果突然需求改了,现在我们必须要用 jQuery 的方法来获取这些元素,我们改怎么办,难道一个个去替换吗?
下面我们分别测试一下通过我们自己写的方法和 jQuery 方法获取元素有哪些不同。
- console.log(MyQuery("#id"));
- console.log($("#id"));
好了,我们对比发现两种方式获取差别还是蛮大的,但是我们看到我们定义的方法和 jQuery 方法在调用上还是比较相似的,那么这个时候我们就可以通过适配器模式,达到快速替换的效果我们来看一下下面的例子
- MyQuery = jQuery;
我们再来看看
- console.log(MyQuery("#id"));
- console.log($("#id"));
我们发现现在获取到的元素一致了。
上面的示例可能在实际应用中不可取,因为 jq 封装了很多 js 的方法,所以类似取值之类的方法适配后会报错,此处只做示例仅供参考!
不知道大家还记不记得,我们之前在单例模式中演示命名空间的示例。
- var MyQuery = {
- $: function(id) {
- return document.getElementById(id);
- },
- CSS: function(id, key, value) {
- this.$(id).style[key] = value;
- }
- }
我们发现我们这种写法虽然和 jQuery 也有些相似但是,还是有很大区别的就比如我们通过 MyQuery.$() 获取页面元素的 ID 是传入的是参数的名称,但是通过 jQuery 获取页面元素的 ID 传入的是 #+id 的名称。那么这种场景下我们需求变更需要使用 jQuery,那之前用来适配的方法很可能用不上,这个时候,我们只能对 MyQuery 下的每个方法进行一一适配。
- MyQuery.$=function(id){
- return $("#"+id);
- }
- MyQuery.css=function(id,key,value){
- return $("#"+id).css(key,value);
- }
- 我们试着调用看一下效果
- console.log(MyQuery.$("id"));
- MyQuery.css("id","background-color","red");
通过上面个示例,我们发现如果两种框架结构比较相近,我们适配会容易很多,如果结构相差很大,我们适配起来可能会很复杂。
当然适配器的作用不仅仅限于上面两个例子,它还有很多用途,比如我们现在要讲的参数适配器
在定义一个多参数的方法的时候我们或多或少都这样写过
- function TestMothed(id, name, age, sex) {}
但是我们这样定义很不友好,如果参数传递的顺序错了也很麻烦,为了规避这种问题,我们把需要传递的参数合并到一个对象里去,然后传递这个对象。
- var o = {
- id: 1,
- name: "张三",
- age: 17,
- sex: "男"
- }
- function TestMothed(obj) {}
不过如果我们使用参数传递,有的时候无法保证传递参数的完整性,如果业务需要增加一个默认值的字段,我们需要在每一个调用的地方去增加相应的字段,也很麻烦
这个时候我们就可以使用适配器来适配传入的这个参数对象。
- function TestMothed(obj) {
- var _o = {
- id: 2,
- name: "李四",
- age: 18,
- sex: "男",
- hobby: "篮球"
- }
- for (var i in _o) {
- _o[i] = obj[i] || _o[i];
- }
- return _o;
- }
我们来调用看看结果
- console.log(TestMothed(o));
现在我们看到,参数中虽然没有传递 hobby 属性,但是通过适配器我们已经把默认值赋值给了对象。
在传统设计模式中,适配器模式往往是适配两个类接口不兼容的问题,然而在 JavaScript 中适配器的应用范围更广,比如适配两个代码库,适配前后端数据等。
JavaScript 中的适配器的应用,更多应用于对象之间,为了使对象可用,通常我们会将对象拆分并重新包装,这样我们就要了解适配对象的内部结构,这也是与外观模式的区别所在,当然适配器模式同样解决了对象之间的耦合度。包装的适配器虽然增加了一些资源开销,但是这些开销几乎可以忽略。
也谢谢大家看到这里:)如果你觉得我的分享还可以请点击推荐,分享给你的朋友让我们一起进步~
好了以上就是本次分享的全部内容,本次示例参考自 JavaScript 设计模式一书,让我们一点点积累一点点成长,希望对大家有所帮助。
来源: http://www.cnblogs.com/chen-jie/p/JavaScript-Adapter.html