设计模式中的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 相关文章推荐
Domino中运用jQuery读取视图内容的方法
Oct 21 Javascript
js以对象为索引的关联数组
Jul 04 Javascript
jquery下为Event handler传递动态参数的代码
Jan 06 Javascript
最常用的12种设计模式小结
Aug 09 Javascript
javascript分页代码(当前页码居中)
Sep 20 Javascript
简略说明Javascript中的= =(等于)与= = =(全等于)区别
Apr 16 Javascript
JS 按钮点击触发(兼容IE、火狐)
Aug 07 Javascript
浅析JavaScript中的typeof运算符
Nov 30 Javascript
JS中关于事件处理函数名后面是否带括号的问题
Nov 16 Javascript
JS使用ActiveXObject实现用户提交表单时屏蔽敏感词功能
Jun 20 Javascript
uni-app之APP和小程序微信授权方法
May 09 Javascript
javascript严格模式详解(含严格模式与非严格模式的区别)
Nov 12 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
php面向对象的方法重载两种版本比较
2008/09/08 PHP
php 上一篇,下一篇文章实现代码与原理说明
2010/05/09 PHP
php GeoIP的使用教程
2011/03/09 PHP
解析PHP自带的进位制之间的转换函数
2013/06/08 PHP
Yii安装与使用Excel扩展的方法
2016/07/13 PHP
PHP中spl_autoload_register()函数用法实例详解
2016/07/18 PHP
PHP Filter过滤器全面解析
2016/08/09 PHP
jquery应该如何来设置改变按钮input的onclick事件
2012/12/10 Javascript
PHP中使用微秒计算脚本执行时间例子
2014/11/19 Javascript
jq实现左侧显示图片右侧文字滑动切换效果
2015/08/04 Javascript
AngularJS使用ngMessages进行表单验证
2015/12/27 Javascript
jQuery实现带遮罩层效果的blockUI弹出层示例【附demo源码下载】
2016/09/14 Javascript
Bootstrap字体图标无法正常显示的解决方法
2016/10/08 Javascript
前端必备插件之纯原生JS的瀑布流插件Macy.js
2017/11/22 Javascript
Vue引用第三方datepicker插件无法监听datepicker输入框的值的解决
2018/01/27 Javascript
Vue+ElementUI实现表单动态渲染、可视化配置的方法
2018/03/07 Javascript
微信小程序商品详情页的底部弹出框效果
2020/11/16 Javascript
layui获取多选框中的值方法
2018/08/15 Javascript
JS散列表碰撞处理、开链法、HashTable散列示例
2019/02/08 Javascript
JS重学系列之聊聊new操作符
2019/03/04 Javascript
vue编写简单的购物车功能
2021/01/08 Vue.js
python中强大的format函数实例详解
2018/12/05 Python
Pyecharts 动态地图 geo()和map()的安装与用法详解
2020/03/25 Python
python 数据类型强制转换的总结
2021/01/25 Python
css3 background属性调整增强介绍
2010/12/18 HTML / CSS
使用CSS实现弹性视频html5案例实践
2012/12/26 HTML / CSS
英国最大的线上保健品零售商之一:Vitamin Planet
2016/12/01 全球购物
结对共建协议书
2014/08/20 职场文书
2014党员学习兰辉先进事迹思想汇报
2014/09/17 职场文书
考试作弊被抓检讨书
2014/10/02 职场文书
2014年党建工作汇报材料
2014/10/27 职场文书
2016寒假社会实践心得体会范文
2015/10/09 职场文书
干部作风纪律整顿心得体会
2016/01/23 职场文书
人物搭配车车超萌联名预备中 【咒术迴战】 ⨯ 【天竺鼠车车】 展开合作
2022/04/11 日漫
SQL Server中T-SQL标识符介绍与无排序生成序号的方法
2022/05/25 SQL Server
MySQL使用IF语句及用case语句对条件并结果进行判断 
2022/09/23 MySQL