JS 外观模式

1. 简介

外观模式(Facade)为子系统中的一组接口提供了一个一致的界面,此模块定义了一个高层接口,这个接口值得这一子系统更加容易使用。 外观模式在JS中常常用于解决浏览器兼容性问题。

2. 实现

外观模式不仅简化类中的接口,而且对接口与调用者也进行了解耦。外观模式经常被认为开发者必备,它可以将一些复杂操作封装起来,并创建一个简单的接口用于调用。 外观模式经常被用于JavaScript类库里,通过它封装一些接口用于兼容多浏览器,外观模式可以让我们间接调用子系统,从而避免因直接访问子系统而产生不必要的错误。

外观模式的优势是易于使用,而且本身也比较轻量级。但也有缺点 外观模式被开发者连续使用时会产生一定的性能问题,因为在每次调用时都要检测功能的可用性。 下面是一段未优化过的代码,我们使用了外观模式通过检测浏览器特性的方式来创建一个跨浏览器的使用方法。

比如对document对象添加click事件的时候:

function addEvent(dom, type, fn) {
  if (dom.addEventListener) {      // 支持DOM2级事件处理方法的浏览器
    dom.addEventListener(type, fn, false)
  } else if (dom.attachEvent) {    // 不支持DOM2级但支持attachEvent
    dom.attachEvent('on' + type, fn)
  } else {
    dom['on' + type] = fn      // 都不支持的浏览器
  }
}

const myInput = document.getElementById('myinput')
addEvent(myInput, 'click', function() {console.log('绑定 click 事件')})

还可以用来解决一些其他的浏览器兼容性问题:

const getEvent = function(event) {  // 获取事件对象
  return event || window.event      // IE下window.event
}

const getTarget = function(event) {        // 获取事件元素
  const event = getEvent(event)
  return event.target || event.srcElement  // IE下event.srcElement
}

const preventDefault = function(event) {    // 阻止默认事件
  const event = getEvent(event)
  if (event.preventDefault) {event.preventDefault()}
  else {event.returnValue = false}          // IE下
}

const cancelBubble = function(event) {
  const event = getEvent(event)
  if (event.stopPropagation) {event.stopPropagation()}
  else {event.cancelBubble = true}      // IE下
}

document.onclick = function(e) {
  preventDefault(e)
  if (getTarget(e) !== document.getElementById('myinput')) {console.log('呵呵')}
}

3. 总结

那么何时使用外观模式呢?一般来说分三个阶段:

  1. 在设计初期,应该要有意识地将不同的两个层分离,比如经典的三层结构,在数据访问层和业务逻辑层、业务逻辑层和表示层之间建立外观Facade。
  2. 在开发阶段,子系统往往因为不断的重构演化而变得越来越复杂,增加外观Facade可以提供一个简单的接口,减少他们之间的依赖。
  3. 在维护一个遗留的大型系统时,可能这个系统已经很难维护了,这时候使用外观Facade也是非常合适的,为系统开发一个外观Facade类,为设计粗糙和高度复杂的遗留代码提供比较清晰的接口,让新系统和Facade对象交互,Facade与遗留代码交互所有的复杂工作。

本文是系列文章,可以相互参考印证,共同进步~

  1. JS 抽象工厂模式
  2. JS 工厂模式
  3. JS 建造者模式
  4. JS 原型模式
  5. JS 单例模式
  6. JS 回调模式
  7. JS 外观模式
  8. JS 适配器模式
  9. JS 利用高阶函数实现函数缓存(备忘模式)
  10. JS 状态模式
  11. JS 桥接模式
  12. JS 观察者模式

网上的帖子大多深浅不一,甚至有些前后矛盾,在下的文章都是学习过程中的总结,如果发现错误,欢迎留言指出~

参考: 设计模式之外观模式 《Javascript 设计模式》 - 张荣铭

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • JS 原型模式

    原型模式(Prototype pattern),用原型实例指向创建对象的类,使用于创建新的对象的类的共享原型的属性与方法。

    前端下午茶
  • Vue项目数据动态过滤实践

    这个问题是在下在做一个Vue项目中遇到的实际场景,这里记录一下我遇到问题之后的思考和最后怎么解决的(老年程序员记性不好 -。-),过程中会涉及到一些Vue源码的...

    前端下午茶
  • CSS margin合并问题

    在CSS当中,相邻的两个盒子(可能是兄弟关系也可能是祖先关系)的外边距可以结合成一个单独的外边距。这种合并外边距的方式被称为折叠,并且因而所结合成的外边距称为折...

    前端下午茶
  • Event(事件)的传播与冒泡

    特性说明和原理图: 标准浏览器和Ie9+浏览器都支持事件的冒泡和捕获,而IE8-浏览器只支持冒泡 标准和Ie9+浏览器用stopPropagation()或c...

    sam dragon
  • js事件浏览器兼容案例

    提莫队长
  • 向zepto.js学习如何手动(trigger)触发DOM事件

    本文作者:IMWeb 谦龙 原文出处:IMWeb社区 未经同意,禁止转载 前言 前端在最近几年实在火爆异常,vue、react、angular各路框...

    IMWeb前端团队
  • 如何阻止冒泡&&浏览器默认行为

    很多同学对阻止事件冒泡和阻止事件默认行为容易混淆,项目中因为一些原因也需要阻止浏览器的一些默认行为,这里就简单总结一下。

    Jerremy
  • 第43天:事件对象event

    一、事件对象 事件:onmouseover、 onmouseout、 onclick event //事件的对象

    半指温柔乐
  • 网页屏蔽各种按键的代码分享

    用户1456630
  • 向zepto.js学习如何手动(trigger)触发DOM事件

    最近一直在看zepto的源码,希望通过学习它掌握一些框架设计的技巧,也将很久不再拾起的js基础重新温习巩固一遍。如果你对这个系列感兴趣,欢迎点击下方地址watc...

    IMWeb前端团队

扫码关注云+社区

领取腾讯云代金券