摘要:桥接模式的核心在于将抽象部分和它的实现部分分离,使它们都可以独立的变化。看起来这个版本已经很完美了不,它仍然有可以优化的空间,即题目提到的桥接模式。使用桥接模式的实现版本这个实现包含了三个函数。这个例子体现了桥接模式的作用。
我写的程序员面试系列文章
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就白白创建了。
实现版本3var 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)来实现不需要全局变量的饱汉式单例模式。
实现版本4var 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的原创技术文章,请关注公众号"汪子熙"或者扫描下面二维码:
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/98590.html
摘要:采用的生成非波拉契数列提供了原生的支持,语法非常有特色,关键字后面紧跟一个星号。的详细介绍参考官网先看如何用这个黑科技重新实现非波拉契树立的生成。在这个内部,我们定义了一个无限循环,用于计算非波拉契数列。 程序员面试系列 Java面试系列-webapp文件夹和WebContent文件夹的区别? 程序员面试系列:Spring MVC能响应HTTP请求的原因? Java程序员面试系列-什么...
摘要:全网最贴心系列教程和配套代码欢迎关注个人技术博客。所以我花费了个多月整理了这份教程,一共分成节,每节都有讲解,并且准备了配套代码。奈何深感水平不够,只有一腔热情,所以直接开放了教程和源码。 webpack-demos:全网最贴心 webpack 系列教程和配套代码 欢迎关注个人技术博客:godbmw.com。每周 1 篇原创技术分享!开源教程(webpack、设计模式)、面试刷题(偏前...
摘要:桥接模式之特权函数特权函数,用一些具有特权的方法作为桥梁以便访问私有空间,可以回忆一下之前的系列。连续自然数分组,计算最多组的个数将至这个连续自然数分成组使每组相加的值相等。个数组中数字最多的一组有个此时的和为。 本回内容介绍 上一回,聊了适配器模式,图片预加载,介一回,聊桥接模式(Bridge),跟之前一样,难度比较小,桥接模式将抽象部分与它的实现部分分离,通过桥接模式联系彼此,同时...
摘要:我的目标是使本系列成为关于应用程序性能的完整指南。代码分割就是将应用程序分割成这些延迟加载的块。总结延迟加载是提高应用程序性能并减少其大小的最佳方法之一。在本系列的下一部分中,我将向您展示如何使用和路由来分割应用程序代码。 当移动优先(mobile-first)的方式逐渐成为一种标准,而不确定的网络环境因素应该始终是我们考虑的一点,因此保持让应用程序快速加载变得越来越困难。在本系列文章...
摘要:函数式编程前端掘金引言面向对象编程一直以来都是中的主导范式。函数式编程是一种强调减少对程序外部状态产生改变的方式。 JavaScript 函数式编程 - 前端 - 掘金引言 面向对象编程一直以来都是JavaScript中的主导范式。JavaScript作为一门多范式编程语言,然而,近几年,函数式编程越来越多得受到开发者的青睐。函数式编程是一种强调减少对程序外部状态产生改变的方式。因此,...
阅读 3693·2021-11-17 09:33
阅读 3262·2021-10-08 10:05
阅读 3082·2021-09-22 15:36
阅读 1053·2021-09-06 15:02
阅读 2745·2019-08-29 12:45
阅读 1565·2019-08-26 13:40
阅读 3371·2019-08-26 13:37
阅读 384·2019-08-26 13:37