再起航,我的学习笔记之JavaScript设计模式11(外观模式)
经过一段时间的学习与分享,我们对创建型设计模式已经有了一定的认识,未来的一段时间里我们将展开新的篇章,开始迈入结构性设计模式的学习。
结构性设计模式与创建型设计模式不同,结构性设计模式更偏向于关注如何将类和对象组合成更大、更复杂的结构,以简化设计。
外观模式
外观模式(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(外观模式)的更多相关文章
- 再起航,我的学习笔记之JavaScript设计模式08(建造者模式)
我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 前几 ...
- 再起航,我的学习笔记之JavaScript设计模式09(原型模式)
我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 我们 ...
- 再起航,我的学习笔记之JavaScript设计模式14(桥接模式)
桥接模式 桥接模式(Bridge): 在系统沿着多个维度变化的同时,又不增加其复杂度并已达到解耦 从定义上看桥接模式的定义十分难以理解,那么我们来通过示例来演示什么是桥接模式. 现在我们需要做一个导航 ...
- 再起航,我的学习笔记之JavaScript设计模式17(模板方法模式)
模板方法模式 由模板方法模式开始我们正式告别结构型设计模式,开始行为型设计模式的学习分享 行为型设计模式用于不同对象之间职责划分或算法抽象,行为型设计模式不仅仅涉及类和对象,还涉及类或对象之间的交流模 ...
- 再起航,我的学习笔记之JavaScript设计模式20(策略模式)
策略模式 策略模式(Strategy):将定义的一组算法封装起来,使其相互之间可以替换.封装的算法具有一定的独立性,不会随客户端变化而变化. 其实策略模式在我们生活中可应用的地方还是比较多的,比如在商 ...
- 再起航,我的学习笔记之JavaScript设计模式22(访问者模式)
访问者模式 概念介绍 访问者模式(Visitor): 针对于对象结构中的元素,定义在不改变该对象的前提下访问结构中元素的新方法 解决低版本IE兼容性 我们来看下面这段代码,这段代码,我们封装了一个绑定 ...
- 再起航,我的学习笔记之JavaScript设计模式24(备忘录模式)
备忘录模式 概念介绍 备忘录模式(Memento): 在不破坏对象的封装性的前提下,在对象之外捕获并保存该对象内部的状态以便日后对象使用或者对象恢复到以前的某个状态. 简易分页 在一般情况下我们需要做 ...
- 再起航,我的学习笔记之JavaScript设计模式25(迭代器模式)
迭代器模式 概念介绍 迭代器模式(Iterator): 在不暴露对象内部结构的同时,可以顺序地访问聚合对象内部的元素. 迭代器 程序中的循环是一种利器,循环语句也使我们程序开发更简洁高效,但是有时一遍 ...
- 再起航,我的学习笔记之JavaScript设计模式26(解释器模式)
解释器模式 概念介绍 解释器模式(Interpreter):给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子. 获取元素在页面中的路径 我们都知道获取一个 ...
随机推荐
- Python如何实现单步调试
遇到大型python项目,如何定位问题和监控程序的运行状态是一个程序员必须掌握的技能,今天小编为你带来python程序的单步调试方法,方便易用,简单易记! 首先你需要在所调试程序的开头中:import ...
- 详解equals()方法和hashCode()方法
前言 Java的基类Object提供了一些方法,其中equals()方法用于判断两个对象是否相等,hashCode()方法用于计算对象的哈希码.equals()和hashCode()都不是final方 ...
- spring boot 读取配置文件信息
1.读取application.properties @Component @ConfigurationProperties(prefix="images.product.column&qu ...
- Python 批量翻译 使用有道api;
妹子是做翻译相关的,遇到个问题,要求得到句子中的所有单词的 音标; 有道翻译只能对单个单词翻译音标,不能对多个单词或者句子段落翻译音标; 手工一个一个翻的话那就要累死人了.....于是就让我写个翻译音 ...
- Java 9 揭秘(13. Collection API 更新)
Tips 做一个终身学习的人. 在本章中,主要介绍以下内容: 在JDK 9之前如何创建了不可变的list,set和map以及使用它们的问题. 如何使用JDK 9中的List接口的of()静态工厂方法创 ...
- 小白也能看懂插件化DroidPlugin原理(一)-- 动态代理
前言:插件化在Android开发中的优点不言而喻,也有很多文章介绍插件化的优势,所以在此不再赘述.前一阵子在项目中用到 DroidPlugin 插件框架 ,近期准备投入生产环境时出现了一些小问题,所以 ...
- Invert a binary tree 翻转一棵二叉树
Invert a binary tree 翻转一棵二叉树 假设有如下一棵二叉树: 4 / \ 2 7 / \ / \ 1 3 6 9翻转后: 4 / \ 7 ...
- 有关Android插件化思考
最近几年移动开发业界兴起了「 插件化技术 」的旋风,各个大厂都推出了自己的插件化框架,各种开源框架都评价自身功能优越性,令人目不暇接.随着公司业务快速发展,项目增多,开发资源却有限,如何能在有限资源内 ...
- PM2源码浅析
PM2工作原理 最近在玩一个游戏,<地平线:黎明时分>,最终Boss是一名叫黑底斯的人,所谓为人,也许不对,黑底斯是一段强大的毁灭进程,破坏了盖娅主进程,从而引发的整个大陆机械兽劣化故事. ...
- 实施软件测试风险分析&回归用例刷选
[一两年前收集整理的资料,感觉不错,放到博客上来] 作为软件测试计划的一部分,软件测试风险的分析与控制是其中重要的环节.如果前期风险分析与控制比较充分,那么会使软件的测试成功性大大增加,且可将由风险异 ...