听飞狐聊JavaScript设计模式系列10

智码云帆
• 阅读 4386

本回内容介绍

上一回,聊了代理模式,虚拟代理,图片懒加载,介一回,也比较容易,适配器模式(Adapter),用一个新的接口对现有类的接口进行包装,处理类与API的不匹配。使用这种模式的对象又叫做包装器(wrapper)。先看个简单的例子,先理解再深入,走你:

1.适配器模式

先定义一个接口(接收3个参数),再定义一个对象,如何衔接二者呢,如下:

// 定义一个接口方法,传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);    //飞狐就是帅,撸壕,大卫

这是模拟JS设计模式书上例子,适配器的作用主要是对现有的接口进行包装,从而实现现有的接口和不兼容的类进行匹配。
这里很多盆友会疑惑适配器模式与门面模式的区别:
1,门面模式是为了简化一个接口,并不提供额外的选择;
2,适配器则要把一个接口转换为另一个接口,并不会滤除某些能力,也不会简化接口;
网上最多的一个例子,就是适配不同的库,如下:

2. 适配不同库

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

<div id="fox1">飞狐</div><br/>
<div id="fox2">帅狐</div><br/>    
<div id="fox3">主要看气质</div>
// 模拟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);

这个例子在网上太多了,随便找了一个来改,目的在于模拟不同库直接的匹配,灵活的转换,解决与现有API提供的接口不兼容的冲突。

听飞狐聊JavaScript设计模式系列10
装逼时刻了,老片新看,推荐《重庆森林》,文艺范儿的调调~~

这一回聊适配器模式,就俩例子,内容不多,主要是理解。
下面的内容来一个图片预加载,跟上一回的懒加载凑一对兄弟篇。

JS图片预加载

图片预加载是web开发中一种应用相当广泛的技术,比如图片翻转显示等特效的时候,为了让图片在转换的时候不出现等待,先让图片下载到本地,再继续执行后续的操作:

//要加载的图片地址,这里可以随便在网上搜点儿图片测试
var imgs=[
    "xxx.jpg",
    "yyy.jpg",
    "zzz.jpg"
    ];
    
var preload=function(imgs,callback){
    // 判断传入的imgs是否为数组(typeof操作符检测数组的时候也是object),若不是数组则用[imgs]转为数组
    var imgs=(typeof imgs!="object")? [imgs] : imgs;
    // 定义一个图片数组
    var img = [];
    for(var i=0,len=imgs.length;i<len;i++){
        // 为每一个图片对象赋值图片地址
        img[i] = new Image();
        img[i].src = imgs[i];
    }
    
    // 三目运算没什么好说的,len-1表示最后一个图片对象,加载完成执行回调函数,apply还记得吧,使作用域指向img
    img[len-1].onload = callback?callback.apply(img):null;
}
    
// 测试
window.onload=function(){
    preload(imgs,function(){
        var _self = this;
        _self.forEach(function(item){
            alert(item.src);
        })
    });
}

这里只是简单的模拟,代码量少,应该可以很容易看懂,预加载减去了等待时间提高用户体验,很多web应用中广泛运用。

这一回,主要聊了适配器模式,图片预加载,主要还是理解~~
下一回,聊一聊桥接模式,顺便做一做计算题。

客观看完点个赞,推荐推荐呗,嘿嘿~~


注:此系飞狐原创,转载请注明出处

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
美凌格栋栋酱 美凌格栋栋酱
6个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Wesley13 Wesley13
3年前
java模式之一
代理模式的概念:对其他对象提供一种代理以控制对这个对象的访问代理模式的三种实现(1)静态代理静态代理在使用时,需要定义接口或者父类,被代理对象与代理对象一起实现相同的接口或者是继承相同父类.eg publicinterfacePammerDao{   voiddomain();}publicTargetimpl
Wesley13 Wesley13
3年前
Java设计模式(一)
Structuralpatterns结构型模式1.适配器模式(Adaptor)目的:将某个类/接口转换为client期望的其他形式。适配器让类可以协同工作,否则就会因为不兼容的接口而无法工作。通过增加一个接口,将已存在的子类封装起来,client面向接口编程,从而隐藏了具体子类。假设我们有一个MediaPlayer接口和一个实现了
Wesley13 Wesley13
3年前
Java Design Patterns
java的设计模式大体上分为三大类:创建型模式(5种):工厂方法模式,抽象工厂模式,单例模式,建造者模式,原型模式。结构型模式(7种):适配器模式,装饰器模式,代理模式,外观模式,桥接模式,组合模式,享元模式。行为型模式(11种):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模
Wesley13 Wesley13
3年前
00_设计模式之语言选择
设计模式之语言选择设计模式简介背景设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。设计模式(Designpattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的
Wesley13 Wesley13
3年前
Java设计模式之命令模式
介绍命令模式是一种行为型设计模式。在命令模式中,所有的请求都会被包装成为一个对象。参考了一下其他关于命令模式的文章,其中有谈到说是可以用不同的请求对客户进行参数化。对这句话的理解是,因为将请求封装成为对象,所以客户的所有操作,其实就是多个命令类的对象而已,即参数化了。命令模式的最大的特点就是将请求的调用者与请求的最终执行者进行了解
Wesley13 Wesley13
3年前
JavaWeb之动态代理解决request请求编码问题
动态代理解决编码问题1.设计模式出现原因:软件开发过程中,遇到相似问题,将问题的解决方法抽取模型(套路)常见设计模式:单例,工厂,适配器,装饰者,动态代理。2.装饰者模式简单介绍谷歌汽车开发场景1.Java定义了汽车开发约定interfaceICar{s
Wesley13 Wesley13
3年前
Java适配器设计模式 的优缺点
1\.定义:将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。2\.适配器模式的本质转换匹配,复用功能。3\.优点:更好的复用如果功能是已经有了的,只是接口不兼容,那么通过适配器模式就可以让这些功能得到更好的复用。更好的可扩展在实现适配器功能的时候,可以调用自己
Wesley13 Wesley13
3年前
Java中的设计模式
注:基于《Java高并发编程详解汪文君》、《深入理解JVM高级特性与最佳实践周志明》,以学习为目的,加上自身理解、验证。作为笔记,为加深印象,做到不复制,不粘贴。欢迎,大家一起交流学习。适配器模式如果当前类的接口不适用与客户端,那么把它转换为客户端所能接受的另一种接口就是适配器模式。从而使得两个接口不匹配而无法在一起工作的两个类能够在一起
待兔 待兔
1年前
Java设计模式之 - 代理模式
代理模式的介绍:代理模式也称为委托模式,在开发中经常用到,是编程的好帮手,在日常生活中也比较常见。比如公司中午让同事帮忙带一份饭,比如我们请一个律师打官司,比如我们用代理服务器上网等等。代理模式真是无处不在。代理模式的定义:为其它对象提供一种代理以控制对这
智码云帆
智码云帆
Lv1
一个人真好,不用迁就别人,别人也不用忍我。
文章
4
粉丝
0
获赞
0