经过一段时间的学习与分享,我们对创建型设计模式已经有了一定的认识,未来的一段时间里我们将展开新的篇章,开始迈入结构性设计模式的学习。

结构性设计模式与创建型设计模式不同,结构性设计模式更偏向于关注如何将类和对象组合成更大、更复杂的结构,以简化设计。

外观模式

外观模式(Facede): 为一组复杂的子系统接口提供一个更高级的统一接口,通过这个接口使得对子系统接口的访问更容易。在JavaScript中有时也会用于对底层结构兼容性做统一的封装来简化用户使用。

这个含义看上去有点抽象,下面我将通过示例为大家演示外观模式,但是在了解外观模式之前,我们先讲一下,我们接下来例子中会演示的dom0级事件和dom2级事件

DOM0级事件

DOM0级事件主要是指on+事件类型,比如我们的onclick事件。

其实在W3C标准里是是没有DOM0级的。但是在我们平时阅读的时候可能会读到DOM0级(DOM Level0)的字眼。实际上,DOM0级标准是不存在的,所谓的DOM0级是DOM历史坐标中的一个参照点而已,具体说呢,DOM0级指的是IE4和Netscape 4.0这些浏览器最初支持的DHTML,大概2000年的时候争论过DOM0的问题,最后结论大概是,没有官方形成此标准。

dom0级事件有个特点就是后定义的事件处理会覆盖前面的。我们来看一个示例:

document.getElementById('btn').onclick=function(){
console.log('第一个点击事件');
}
document.getElementById('btn').onclick=function(){
console.log('第二个点击事件');
}

现在我们看看结果,我们发现后面定义的事件果然覆盖了前面的事件。

DOM2级事件

DOM2级事件主要是指addEventListener(events,handler,boolean),removeEventListener(events,handler)这类事件

当然DOM2级事件的特点是不会覆盖自身,而且和DOM0级事件也能共存。我们来看下面的示例。

document.getElementById('btn').addEventListener("click",function(){
console.log("监听第一个点击事件");
})
document.getElementById('btn').addEventListener("click",function(){
console.log("监听第二个点击事件");
})

我们可以看到,我们为btn绑定的两个点击事件均被触发。

此处我们只简单介绍这两个级别的事件其他事件如果有兴趣大家可以自行查阅资料

那么我们现在讲的DOM0级事件和DOM2级事件和外观模式又有什么联系呢?

我们都知道浏览器的兼容是个很麻烦的事情,就比如我们的addEventListener监听事件在老版本的IE浏览器是不支持的,所以那些老版本的浏览器我们要用attachEvent来实现,当然如果碰到了不支持DOM2级事件处理的浏览器,那么我们只能用on事件方法去绑定事件

所以这个时候我们就可以用外观模式去封装他们。

外观模式

如同我们定义里说的一样为一组复杂的子系统接口提供一个更高级的统一接口,我们通过下面这个示例为大家演示外观模式

function addEvent(dom,type,fn){
//对于支持DOM2级事件并且支持监听事件的浏览器我们使用监听事件
if(dom.addEventListener){
dom.addEventListener(type,fn);
}//对于支持DOM2级事件但不支持监听事件的浏览器我们用attachEvent方法
else if(dom.attachEvent){
dom.attachEvent('on'+type,fn);
}//对于不支持DOM2级事件的浏览器,我们只能用on+'事件名'的DOM0级事件方式
else{
dom['on'+type]=fn;
}
}

我们来试一试

var btn=document.getElementById('btn');
addEvent(btn,'click',function(){
console.log("绑定第一个事件")
})
addEvent(btn,'click',function(){
console.log("绑定第二个事件")
})

因为浏览器版本支持监听事件所以我们触发了第一种方法

进一步解决兼容问题

从我们上面的介绍其实我们可以进一步延伸,很多兼容问题我们都可以通过外观模式去解决,比如低版本的IE不兼容preventDefault方法和target属性,那么我们同样可以通过外观模式来解决

var getEvent=function(event){
//标准浏览器返回event,IE返回window.event
return event||window.event;
}
var getTarget=function(event){
var event=getEvent(event);
//标准浏览器返回target,IE返回srcElement
return event.target||event.srcElement;
}
var preventDefault=function(event){
var event=getEvent(event);
//标准浏览器
if(event.preventDefault){
event.preventDefault();
}//IE浏览器
else{
event.returnValue=false;
}
}

我们来试一下

document.onclick=function(e){
//阻止默认行为
preventDefault(e);
//获取事件源目标对象
if(getTarget(e)!==document.getElementById('btn')){
console.log("阻止");
}
}

我们看到只要在我们btn按钮之外的地方点击,这个事件都会输出阻止

总结

通过外观模式,对接口的二次封装隐藏其复杂性,并简化其使用是一种不错的时间,当然这种实践多少都会增加一些资源的开销以及程序的复杂度。不过这种开销对于使用成本来说是可以忽略的。

外观模式是对接口方法的外层包装,以供上层代码调用。因此有时外观模式封装的接口方法不需要接口的具体实现,只需要按照接口使用规则使用即可。这也是对系统与客户之间的一种松散耦合。使得系统与客户之间不会因结构的变化而互相 影响。

也谢谢大家看到这里:)如果你觉得我的分享还可以请点击推荐,分享给你的朋友让我们一起进步~

好了以上就是本次分享的全部内容,本次示例参考自JavaScript设计模式一书,让我们一点点积累一点点成长,希望对大家有所帮助。

欢迎转载,转载请注明作者,原文出处。

再起航,我的学习笔记之JavaScript设计模式11(外观模式)的更多相关文章

  1. 再起航,我的学习笔记之JavaScript设计模式08(建造者模式)

    我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 前几 ...

  2. 再起航,我的学习笔记之JavaScript设计模式09(原型模式)

    我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 我们 ...

  3. 再起航,我的学习笔记之JavaScript设计模式14(桥接模式)

    桥接模式 桥接模式(Bridge): 在系统沿着多个维度变化的同时,又不增加其复杂度并已达到解耦 从定义上看桥接模式的定义十分难以理解,那么我们来通过示例来演示什么是桥接模式. 现在我们需要做一个导航 ...

  4. 再起航,我的学习笔记之JavaScript设计模式17(模板方法模式)

    模板方法模式 由模板方法模式开始我们正式告别结构型设计模式,开始行为型设计模式的学习分享 行为型设计模式用于不同对象之间职责划分或算法抽象,行为型设计模式不仅仅涉及类和对象,还涉及类或对象之间的交流模 ...

  5. 再起航,我的学习笔记之JavaScript设计模式20(策略模式)

    策略模式 策略模式(Strategy):将定义的一组算法封装起来,使其相互之间可以替换.封装的算法具有一定的独立性,不会随客户端变化而变化. 其实策略模式在我们生活中可应用的地方还是比较多的,比如在商 ...

  6. 再起航,我的学习笔记之JavaScript设计模式22(访问者模式)

    访问者模式 概念介绍 访问者模式(Visitor): 针对于对象结构中的元素,定义在不改变该对象的前提下访问结构中元素的新方法 解决低版本IE兼容性 我们来看下面这段代码,这段代码,我们封装了一个绑定 ...

  7. 再起航,我的学习笔记之JavaScript设计模式24(备忘录模式)

    备忘录模式 概念介绍 备忘录模式(Memento): 在不破坏对象的封装性的前提下,在对象之外捕获并保存该对象内部的状态以便日后对象使用或者对象恢复到以前的某个状态. 简易分页 在一般情况下我们需要做 ...

  8. 再起航,我的学习笔记之JavaScript设计模式25(迭代器模式)

    迭代器模式 概念介绍 迭代器模式(Iterator): 在不暴露对象内部结构的同时,可以顺序地访问聚合对象内部的元素. 迭代器 程序中的循环是一种利器,循环语句也使我们程序开发更简洁高效,但是有时一遍 ...

  9. 再起航,我的学习笔记之JavaScript设计模式26(解释器模式)

    解释器模式 概念介绍 解释器模式(Interpreter):给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子. 获取元素在页面中的路径 我们都知道获取一个 ...

随机推荐

  1. MySQL 'localhost' (10061)解决方法

    今天启动mysql 出现10061错误,处理:修改hosts文件中localhost指向127.0.0.1. 参看:http://www.cnblogs.com/ljian/archive/2011/ ...

  2. vb编程代码大全

    数值型函数:abs(num): 返回绝对值sgn(num): num>0 1; num=0 0; num<0 -1;判断数值正负hex(num): 返回十六进制值 直接表示:&Hx ...

  3. JS的get和set使用示例

    javascript中set与get方法详解 其中get与set的使用方法: 1.get与set是方法,因为是方法,所以可以进行判断. 2.get是得到 一般是要返回的   set 是设置 不用返回 ...

  4. Oracle之plsql快速入门

    打开系统输出 set serveroutput on; 只需要打开一次**书写格式 以斜杠/号 结束(基本结构) --declare --语句后面必须以;号结束 declare --用来区分变量名和表 ...

  5. 2,返回Json

    一,使用Spring Boot默认Json解析框架jackson 1,创建一个实体类Persion package com.zh.json; public class Persion { privat ...

  6. STL—list

    前面我们分析了vector,这篇介绍STL中另一个重要的容器list list的设计 list由三部分构成:list节点.list迭代器.list本身 list节点 list是一个双向链表,所以其li ...

  7. pc端的企业网站(IT修真院test8)详解1-3

    一,base.css基础样式表的意义 我昨天,整理了一下代码规范. 发现现在这个程度的页面还原.有必要创建一个规范的base.css库和framework.css库 而且也要为日后的工作整理一些常用的 ...

  8. CentOS7.3虚拟机双网卡配置

    笔者在学习和工作中经常要用到linux,专门装一个linux主机固然可以,但是毕竟还要用到windows,解决的办法就是用vmware来搭建linux虚拟机.关于linux虚拟机上网的问题,笔者写过很 ...

  9. (转)Spring Bean Scope 有状态的Bean 无状态的Bean

    有状态会话bean   :每个用户有自己特有的一个实例,在用户的生存期内,bean保持了用户的信息,即“有状态”:一旦用户灭亡(调用结束或实例结束),bean的生命期也告结束.即每个用户最初都会得到一 ...

  10. (转)JAVA排序汇总

    JAVA排序汇总 package com.softeem.jbs.lesson4; import java.util.Random; /** * 排序测试类 * * 排序算法的分类如下: * 1.插入 ...