我写的程序员面试系列文章

Java面试系列-webapp文件夹和WebContent文件夹的区别?

程序员面试系列:Spring MVC能响应HTTP请求的原因?

Java程序员面试系列-什么是Java Marker Interface(标记接口)

使用JDK自带的工具jstack找出造成运行程序死锁的原因

编程面试题:编写一个会造成数据库死锁的应用

设计模式(Design Pattern)中的桥接模式,有的朋友平时工作可能很少用到。桥接模式的核心在于将抽象部分和它的实现部分分离,使它们都可以独立的变化。听起来很抽象,让我们看一个具体而简单的例子,通过这个例子一步步的完善来加深对桥接模式的理解。

很多论坛点登录按钮时,

周围背景都会暗下来,这样可以突出即将弹出的登录框,让用户把精力集中在用户名和密码的输入上去。

很多论坛对于这种背景变暗的UI实现,是创建了一个HTML原生的div元素,加上一些精心设计过背景颜色的CSS样式来完成的。

我们下面称这种div元素为遮罩层div元素,即mask div。

下面讨论创建mask div的最优解。

实现版本1

创建一个createMask函数,作为登录按钮的事件响应函数。每次点击按钮之后执行该函数。

var createMask = function(){

      return document.body.appendChild( document. createElement('div') );

}

$(‘#logon_button').click(function(){

    var mask = createMask();

    mask.show();

})

版本1的缺点

每次点击按钮都会创建一个mask div。当然一般情况下登录按钮只会点击一次。但是在面试场景中,面试官可能会把这个问题的讨论引导到其他方向上。如何实现即使多次点击按钮,也只会创建一次mask div?于是就有了版本2。

实现版本2

事先创建好一个mask div,放到一个全局变量里保存。这种方式有点像单例模式(singleton)的饿汉式单例。

var mask = document.body.appendChild(document.createElement('div' ) );

$( '#logon_button').click(function(){

     mask.show();

})

版本2的缺点

版本2采用了一个全局变量保存事先创建好的mask div。还记得那句话么?全局变量是万恶之源。

另外,假设用户永远不点登录按钮,只是以游客身份浏览网站,那么这个mask div就白白创建了。

实现版本3


var mask; var createMask = function(){ if(mask) return mask; else{ mask = document,body.appendChild( document.createElement('div') ); return mask; } }

版本3的缺点

虽然使用了饱汉式单例模式,避免了mask div在没有点击登录按钮的情况下不必要的创建,但还是使用了全局变量来存放mask div。要记住我们现在是在用JavaScript,因此可以用它提供的强大的闭包特性(closure)来实现不需要全局变量的饱汉式单例模式。

实现版本4

var createMask = function() {

   var mask;

   return function() {

       return mask || ( mask = document.body.appendChild(document.createElement('div')));

}

}();

借助JavaScript的闭包特性,我们在第二行创建的自由变量(Free variable)只在闭包内部可见,外部消费者感知不到这个变量,因此成为存储mask div的最佳选择。看起来这个版本已经很完美了?不,它仍然有可以优化的空间,即题目提到的桥接模式。

版本4的缺点

从单一职责原理(Single Responsibility)来衡量版本4,createMask函数里实际包含了两种不同类型的逻辑:

1. 创建mask div

2. 使该mask div “单例化”

我们下面使用桥接模式将这两种逻辑分开,来实现最终版本。

使用桥接模式的实现版本5

这个实现包含了三个JavaScript函数。首先看singleton函数。

函数singleton的输入参数是另一个JavaScript函数(我称其为原始函数),输出是一个包装后的函数,其内部使用闭包,将原始函数第一次执行的结果保存在闭包内,当包装后的函数第二次执行时,直接返回闭包内保存的第一次执行结果。我们可以把singleton函数当成一个构造器,传入任意一个具有返回值的JavaScript函数,负责生产出具有“单例化”特性的新函数。

var singleton = function(fn){

   var result;

   return function() {

        return result || ( result = fn.apply(this,arguments));

   }

}

var origin = function(){

      return document.body.appendChild(document.createElement('div'));

};

var createMask = singleton(origin);

然后我们调用这个singleton函数,把我们原始的创建mask div的函数origin作为参数传进去,得到加工后的新函数createMask。

这个例子体现了桥接模式的作用。我们通过singleton这个单例化构造器函数,成功将业务逻辑(创建mask div)和单例化这个纯技术需求分离开,这样也满足了单一职责(single responsibility)的设计理念。

要获取更多Jerry的原创技术文章,请关注公众号"汪子熙"或者扫描下面二维码:

JavaScript面试系列:JavaScript设计模式之桥接模式和懒加载的更多相关文章

  1. 【JavaScript】使用纯JS实现多张图片的懒加载(附源码)

    一.效果图如下 上面的效果图,效果需求如下 1.还没加载图片的时候,默认显示加载图片背景图 2.刚开始进入页面,自动加载第一屏幕的图片 3.下拉界面,当一张图片容器完全显露出屏幕,即刻加载图片,替换背 ...

  2. 乐在其中设计模式(C#) - 桥接模式(Bridge Pattern)

    原文:乐在其中设计模式(C#) - 桥接模式(Bridge Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 桥接模式(Bridge Pattern) 作者:webabcd 介绍 ...

  3. java面试题之----jdbc中使用的设计模式(桥接模式)

    1.JDBC(JavaDatabase Connectivity) JDBC是以统一方式访问数据库的API. 它提供了独立于平台的数据库访问,也就是说,有了JDBC API,我们就不必为访问Oracl ...

  4. php设计模式之桥接模式

    php设计模式之桥接模式 一.概述 桥接模式:将两个原本不相关的类结合在一起,然后利用两个类中的方法和属性,输出一份新的结果. 其实就是讲不相关的东西通过类(本例中是SendInfo)结合在一起,从而 ...

  5. java设计模式7——桥接模式

    java设计模式7--桥接模式 1.桥接模式介绍 桥接模式是将抽象部分与它的实现部分分离,使他们都可以独立的变化.它是一种对象结构型模式,又称为柄体模式或接口模式. 2.解决问题 2.1.将复杂的组合 ...

  6. 基于javascript实现图片懒加载(亲测有效)

    这篇文章主要介绍了javascript实现图片懒加载的方法及思路,有时我们需要用懒加载,也就是延迟加载图片的方式,来提高网站的亲和力,需要的朋友可以参考下! 一.定义 图片延迟加载也称为懒加载,延迟加 ...

  7. javascript图片懒加载与预加载的分析

    javascript图片懒加载与预加载的分析 懒加载与预加载的基本概念.  懒加载也叫延迟加载:前一篇文章有介绍:JS图片延迟加载 延迟加载图片或符合某些条件时才加载某些图片. 预加载:提前加载图片, ...

  8. JavaScript之图片懒加载的实现

    图片懒加载指的是在浏览过程中随着需要才被加载出来,例如某宝上面浏览商品时,会伴随很多的图片,如果一次全部加载出来的话,显然资源有些浪费,并且加载速度也会相对降低,那么懒加载的实现很重要.即随着浏览翻阅 ...

  9. 单例设计模式Singleton之懒加载模式(懒汉模式)【原】

    单例设计模式Singleton之懒加载模式(懒汉模式) SingletonLazy.java类 package kingtool; import kingtool.http.IPTool; publi ...

随机推荐

  1. C#控件刷新

    ; ; foreach (string gen in fn_gen) { //MessageBox.Show(gen); Bitmap Bi = new Bitmap(gen); //使用打开的图片路 ...

  2. Java的栈和堆

    JVM的内存区域可以被分为:线程栈,堆,静态方法区(实际上还有更多功能的区域,并且这里说的是JVM的内存区域) 线程栈:      注意这个栈和数据结构中的stack有相似之处,但并不是用户态的.准确 ...

  3. SmartSql使用教程(1)——初探,建立一个简单的CURD接口服务

    一.引言 最近SmartSql被正式引入到了NCC,借着这个契机写一个使用教程系列 二.SmartSql简介[摘自官方文档] 1. SmartSql是什么? SmartSql = MyBatis + ...

  4. iOS 8 之后的动态沙盒路径

    在iOS8之前,我们获取到沙盒中的document.cache.tmp之后,下一次模拟器或真机无论重启多少次,这具体的路径是固定的,可是iOS8 之后,你要是在按原来的路径去找你想要的东西,我想它会把 ...

  5. Qt生成CSV 文件

    1.CSV 文件 不支持 EXCEL中 的多个工作表的模式. 一个 CVS 文件只能转换成 EXCEL 一个工作表. 2.逗号分隔值(Comma-Separated Values,CSV,有时也称为字 ...

  6. lightoj1062【几何(二分)】

    其实就应该想到,哪有那么简单让你直接搞出答案的几何题啊:(而且很有可能是二分? 题意: 有两个梯子,一个靠在左边墙上,一个靠在右边墙上,长度分别为 x 和 y,他们的交点距离地面高度是 c,求两个梯子 ...

  7. laravel 路由设置

    目录  routes\web.php 初始路由,直接渲染视图welcome,即V层   '/'为路径:www.xxx.com/ Route::get('/', function () { return ...

  8. 我叫mt2.0更新公告

    一.2.0版<PVP的远征>军费发放 简体服<我叫MT>2.0版本<PVP的远征>更新在即!为备战新版本,我们宣布10天后(3月10日)发放军费振奋军心. 简体服3 ...

  9. PJzhang:最基本的正则表达式实例

    猫宁!!! 参考链接: https://www.cnblogs.com/fozero/p/7868687.html http://tool.oschina.net/regex/# http://too ...

  10. UVA10140 Prime Distance【素数/数论】By cellur925

    题目传送门 我们注意到,L,R是肥肠大的.........我们不可能在1s内筛出2^31内的全部质数. “上帝为你关上一扇门,同时为你打开一扇窗” 我们又注意到,R-L是肥肠比较小的,珂以从这入手解决 ...