设计模式中的facade外观模式在JavaScript开发中的运用


Posted in Javascript onMay 18, 2016

概念

外观模式(门面模式),是一种相对简单而又无处不在的模式。外观模式提供一个高层接口,这个接口使得客户端或子系统更加方便调用。

外观模式并不是适配器模式,适配器模式是一种包装器,用来对接口进行适配以便在不兼容系统中使用它。而创建外观元素则是图个方便。它并不用于达到需要特定接口的客户系统打交道这个目的,而是用于提供一个简化的接口。

JavaScript代码示例

用一段再简单不过的代码来表示

var getName = function(){
 return ''svenzeng"
}
var getSex = function(){
  return 'man'
}

如果你需要分别调用getName和getSex函数. 那可以用一个更高层的接口getUserInfo来调用.

var getUserInfo = function(){
 var info = a() + b();
 return info;
}

也许你会问为什么一开始不把getName和getSex的代码写到一起, 比如这样

var getNameAndSex = function(){
 return 'svenzeng" + "man";
}

答案是显而易见的,饭堂的炒菜师傅不会因为你预定了一份烧鸭和一份白菜就把这两样菜炒在一个锅里。他更愿意给你提供一个烧鸭饭套餐。同样在程序设计中,我们需要保证函数或者对象尽可能的处在一个合理粒度,毕竟不是每个人喜欢吃烧鸭的同时又刚好喜欢吃白菜。
外观模式还有一个好处是可以对用户隐藏真正的实现细节,用户只关心最高层的接口。比如在烧鸭饭套餐的故事中,你并不关心师傅是先做烧鸭还是先炒白菜,你也不关心那只鸭子是在哪里成长的。
最后写个我们都用过的外观模式例子

var stopEvent = function( e ){  //同时阻止事件默认行为和冒泡
 e.stopPropagation();
 e.preventDefault();
}

我知道外观模式的概念很容易掌握,你都不一定需要一个JavaScript代码的例子,但是总有些人更在乎代码,会觉得那样才更容易理解。更何况,没有代码示例的JavaScript文章根本就不具说服力,就应该从网上删掉。 我们从一个简单的事件监听器的例子开始。大家都知道要添加一个事件监听器并不是一件容易的事,除非只想让代码运行在少数几个浏览器上。你不得不测试很多方法以确保针对不同浏览器的代码都能正常运行。在这个代码示例中我们只是把特性检测添加到这个方法中:

function addEvent(element, type, func) {
  if (window.addEventListener) {
    element.addEventListener(type, func, false);
  }
  else if (window.attachEvent) {
    element.attachEvent('on'+type, func);
  }
  else {
    element['on'+type] = func;
  }
}

简单吧!我真希望我可以不用写那些不必要的代码,让它们越简单越好,但是如果真是这样就没什么意思了,你也不会想读下去了,对吧?所以我不这么认为,我想我要给你看点更复杂的东西。我只是想说,你的代码原本看起来会有些像下面这样:

var foo = document.getElementById('foo');
  foo.style.color = 'red';
  foo.style.width = '150px';

var bar = document.getElementById('bar');
  bar.style.color = 'red';
  bar.style.width = '150px';

var baz = document.getElementById('baz');
  baz.style.color = 'red';
  baz.style.width = '150px';

太蹩脚了!你对每个元素做了一模一样的事!我认为我们可以让它变得更简单点:

function setStyle(elements, property, value) {
  for (var i=0, length = elements.length; i < length; i++) {
    document.getElementById(elements[i]).style[property] = value;
  }
}

// 现在你可以这么写:
setStyle(['foo', 'bar', 'baz'], 'color', 'red');
setStyle(['foo', 'bar', 'baz'], 'width', '150px');

是不是觉得咱们NB坏了?你快算了吧!咱们可是JavaScript程序员呀!能不能用点脑子,来点真格的。也许我们可以只调用一次就能设置所有的样式。看下这个:

function setStyles(elements, styles) {
  for (var i=0, length = elements.length; i < length; i++) {
    var element = document.getElementById(elements[i]);

    for (var property in styles) {
      element.style[property] = styles[property];
    }
  }
}

//现在你只要这样写:
setStyles(['foo', 'bar', 'baz'], {
  color: 'red',
  width: '150px'
});

如果我们有很多元素想设置相同的样式,那这段代码真是为我们节省了不少时间。

外观模式之利:
使用外观模式的目的就是要让程序员过的更轻松一些,编写一次组合代码,然后就可以反复使用它,这有助于节省时间和精力。给一些复杂的问题提供一个简化接口。

外观方法方便了开发人员,斌共提供过了比较高层的功能,降低对外部代码的依赖程度,为应用系统的开发增加了一些额外的灵活性。通过使用外观模式,可以避免与下层子系统紧密耦合。这样就可以对这个系统进行修改而不会影响到客户代码。

外观模式之弊:
有时候外观元素也会带来一些不必要的额外负担。在实施一些套路之前应该认真掂量一下其实用性。有时相比一个庞杂的外观函数,其组成函数在力度方面更有吸引力。这是因为外观函数可能常常会执行一些你并不需要的任务。

对于简单的个人网站或少量营销网页来说,仅为工具提示和弹出式窗口这样一点增强行为就导入这个Javascript库可能并不明智。此时考虑只使用少许简单的外观元素而不是一个满是这类东西的库。

外观函数为执行各种复杂任务提供了一个简单的接口,它们使代码更容易维护和理解。它们还能弱化子系统和客户代码的耦合。把经常相伴出现的常用函数组合在一起。这个模式在DOM脚本编程这种需要面对葛洪不一致的浏览器接口的环境中很常用。

Javascript 相关文章推荐
Javascript下IE与Firefox下的差异兼容写法总结
Jun 18 Javascript
jquery中dom操作和事件的实例学习-表单验证
Nov 30 Javascript
关于JS控制代码暂停的实现方法分享
Oct 11 Javascript
js 实现浏览历史记录示例
Apr 20 Javascript
jquery中使用循环下拉菜单示例代码
Sep 24 Javascript
探寻Javascript执行效率问题
Nov 12 Javascript
整理Javascript流程控制语句学习笔记
Nov 29 Javascript
配置一个vue3.0项目的完整步骤
Apr 26 Javascript
Flexible.js可伸缩布局实现方法详解
Nov 13 Javascript
在HTML中使用JavaScript的两种方法
Dec 24 Javascript
原生JavaScript实现进度条
Feb 19 Javascript
uniapp开发小程序的经验总结
Apr 08 Javascript
JQuery.validate在ie8下不支持的快速解决方法
May 18 #Javascript
12个非常实用的JavaScript小技巧【推荐】
May 18 #Javascript
JQuery解析XML数据的几个简单实例
May 18 #Javascript
JavaScript设计模式开发中组合模式的使用教程
May 18 #Javascript
设计模式中的组合模式在JavaScript程序构建中的使用
May 18 #Javascript
easyui window refresh 刷新两次的解决方法(推荐)
May 18 #Javascript
详解JavaScript设计模式开发中的桥接模式使用
May 18 #Javascript
You might like
javascript 放大镜 v1.0 基于Yui2 实现的放大镜效果
2010/03/08 Javascript
输入自动提示搜索提示功能的使用说明:sugggestion.txt
2013/09/02 Javascript
js点击列表文字对应该行显示背景颜色的实现代码
2015/08/05 Javascript
深入解析JavaScript中函数的Currying柯里化
2016/03/19 Javascript
JavaScript必知必会(六) delete in instanceof
2016/06/08 Javascript
canvas绘制多边形
2017/02/24 Javascript
详解JS数据类型的值拷贝函数(深拷贝)
2017/07/13 Javascript
基于js粘贴事件paste简单解析以及遇到的坑
2017/09/07 Javascript
浅析Vue.js中v-bind v-model的使用和区别
2018/12/04 Javascript
微信小程序开发之点击按钮退出小程序的实现方法
2019/04/26 Javascript
Vue组件为什么data必须是一个函数
2020/06/11 Javascript
解决vue安装less报错Failed to compile with 1 errors的问题
2020/10/22 Javascript
[45:25]完美世界DOTA2联赛循环赛 PXG vs IO 第一场 11.06
2020/11/09 DOTA
Python随机数random模块使用指南
2016/09/09 Python
python实现定时自动备份文件到其他主机的实例代码
2018/02/23 Python
Python入门之后再看点什么好?
2018/03/05 Python
Python打包方法Pyinstaller的使用
2018/10/09 Python
spark dataframe 将一列展开,把该列所有值都变成新列的方法
2019/01/29 Python
python误差棒图errorbar()函数实例解析
2020/02/11 Python
使用python批量修改XML文件中图像的depth值
2020/07/22 Python
一篇文章带你搞定Ubuntu中打开Pycharm总是卡顿崩溃
2020/11/02 Python
python 如何上传包到pypi
2020/12/24 Python
在vscode中启动conda虚拟环境的思路详解
2020/12/25 Python
python实现双人五子棋(终端版)
2020/12/30 Python
python装饰器代码深入讲解
2021/03/01 Python
用gpu训练好的神经网络,用tensorflow-cpu跑出错的原因及解决方案
2021/03/03 Python
浅析rem和em和px vh vw和% 移动端长度单位
2016/04/28 HTML / CSS
Meli Melo官网:名媛们钟爱的英国奢侈手包品牌
2017/04/17 全球购物
JACK & JONES英国官方网站:欧洲领先的男装生产商
2017/09/27 全球购物
Rodd & Gunn澳大利亚官网:新西兰男装品牌
2018/09/25 全球购物
最新教师自我评价分享
2013/11/12 职场文书
质检员的岗位职责
2013/11/15 职场文书
2014年会演讲稿范文
2014/01/06 职场文书
学习三严三实对照检查材料思想汇报
2014/09/22 职场文书
委托书范本格式
2019/04/18 职场文书
Python中的 No Module named ***问题及解决
2022/07/23 Python