最近再准备秋招,然后顺便把过去空白的设计模式相关概念补一补,这些内容都是从《JavaScript设计模式与开发实践》一书中整理出来的

(1)单例模式

定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

适用场景:一个单一对象。比如:登录弹窗,无论点击多少次,登录弹窗只会被创建一次

简单版实现方法:判断实例存在与否,如果存在则直接返回,如果不存在就创建了再返回,这就确保了一个类只有一个实例对象。 拓展:

透明的单例模式:解决了简单单例的不透明性,使用者需知道其是一个单例对象才能进行获取

代理实现单例模式:创建单例和管理单例逻辑分开,管理单例逻辑放在代理类中

惰性单例技术:合适的时候才创建对象,并且只创建唯一的一个

JavaScript中的单例:全局变量当成单例来使用,缺点:命名空间污染

(2)策略模式

定义:将一个个算法(解决方案)封装在一个个策略类中,并且使他们可以相互替换

特点:一个基于策略模式的算法至少由两部分组成,一部分是策略类,封装了具体算法负责计算过程,另一部分是环境类,接受客户请求,将请求托付给某一个策略类

优点:

  • 策略模式可以避免代码中的多重判断条件。

  • 策略模式很好的体现了开放-封闭原则,将一个个算法(解决方案)封装在一个个策略类中。便于切换,理解,扩展。

  • 策略中的各种算法可以重复利用在系统的各个地方,避免复制粘贴。

  • 策略模式在程序中或多或少的增加了策略类。但比堆砌在业务逻辑中要清晰明了。

  • 违反最少知识原则,必须要了解各种策略类,才能更好的在业务中应用。

    应用场景:根据不同的员工绩效计算不同的奖金;表单验证中的多种校验规则。

(3)代理模式

定义:为一个对象提供一个代用品或占位符,以便控制对它的访问。

应用场景:图片懒加载(先通过一张loading图占位,然后通过异步的方式加载图片,等图片加载好了再把完成的图片加载到img标签里面。)

(4)迭代器模式

//TODO

(5)发布/订阅模式

定义:又叫观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。

场景:订阅感兴趣的专栏和公众号。

实现方法:

  • 先指定好发布者

  • 给发布者加一个缓存列表,用于存储回调函数通知订阅者

  • 发布消息时,遍历缓存列表,触发存放的订阅者回调函数

    简单版代码实现:

     let event = {
    clientList: [],
    listen: function(key, fn) {
    if (!this.clientList[key]) {
    // 如果没有订阅过此类消息,则给该类消息创建一个缓存列表
    this.clientList[key] = []
    }
    this.clientList[key].push(fn)
    },
    trigger: function() {
    // 取第一个参数,即key值
    const key = Array.prototype.shift.call(arguments)
    const fns = this.clientList[key]
    // 如果没有订阅该消息则返回
    if (!fns || fns.length === 0) {
    return false
    }
    // 遍历列表
    for (var i = 0, fn; (fn = fns[i]); i++) {
    fn.apply(this, arguments)
    }
    },
    remove: function(key, fn) {
    // 取消订阅
    let fns = this.clientList[key]
    if (!fns) {
    return flase
    }
    if (!fn) {
    // 如果key对应的消息没人订阅则直接返回
    fns && (fns.length = 0)
    } else {
    for (let l = fns.length - 1; l >= 0; l--) {
    let _fn = fns[l]
    if (_fn === fn) {
    fns.splice(l, 1)
    }
    }
    }
    },
    }

    let salesOffices = {}
    installEvent(salesOffices)
    salesOffices.listen('123', fn1 = function(squareMeter) {
    console.log('面积为1:', squareMeter)
    })
    salesOffices.listen('123', fn2 = function(squareMeter) {
    console.log('面积为2:', squareMeter)
    })
    salesOffices.trigger('123', fn1)
    salesOffices.remove('123',fn1)
    salesOffices.trigger('123', fn1)

(6)中介者模式

定义:通过一个中介者对象,其他所有相关对象都通过该中介者对象来通信,而不是互相引用,当其中的一个对象发生改变时,只要通知中介者对象就可以。可以解除对象与对象之间的紧耦合关系。

应用场景: 例如购物车需求,存在商品选择表单、颜色选择表单、购买数量表单等等,都会触发change事件,那么可以通过中介者来转发处理这些事件,实现各个事件间的解耦,仅仅维护中介者对象即可。

(7)装饰者模式

定义:在不改变对象自身的基础上,在程序运行期间给对象动态的添加方法。

应用场景: 有方法维持不变,在原有方法上再挂载其他方法来满足现有需求;函数的解耦,将函数拆分成多个可复用的函数,再将拆分出来的函数挂载到某个函数上,实现相同的效果但增强了复用性。

参考书籍:JavaScript设计模式与开发实践 曾探

前端中的设计模式 JavaScript的更多相关文章

  1. 前端学习 第二弹: JavaScript中的一些函数与对象(1)

    前端学习 第二弹: JavaScript中的一些函数与对象(1) 1.apply与call函数 每个函数都包含两个非继承而来的方法:apply()和call(). 他们的用途相同,都是在特定的作用域中 ...

  2. JavaScript中的设计模式:策略模式

    无论学习前端还是后端设计模式是作为一名程序员不可缺少的知识,就像下底传中对于一个边锋来说. 一.策略模式 策略模式给人的第一感觉就是在代码里面消除了很多if-else分支语句,比如一个求员工奖金的程序 ...

  3. JavaScript 中常见设计模式整理

    开发中,我们或多或少地接触了设计模式,但是很多时候不知道自己使用了哪种设计模式或者说该使用何种设计模式.本文意在梳理常见设计模式的特点,从而对它们有比较清晰的认知. JavaScript 中常见设计模 ...

  4. 从前端中的IOC理念理解koa中的app.use()

    忙里偷闲,打开平时关注的前端相关的网站,浏览最近最新的前端动态.佼佼者,平凡的我做不到,但还是要争取不做落后者. 前端中的IoC理念,看到这个标题就被吸引了.IoC 理念,不认识呢,点击去一看,果然没 ...

  5. 前端试题本(Javascript篇)

    JS1. 下面这个JS程序的输出是什么:JS2.下面的JS程序输出是什么:JS3.页面有一个按钮button id为 button1,通过原生的js如何禁用?JS4.页面有一个按钮button id为 ...

  6. 前端优秀作品展示,JavaScript 版水果忍者

    <水果忍者>是一款非常受喜欢的手机游戏,刚看到新闻说<水果忍者>四周年新版要上线了.网页版的切水果游戏由百度 JS 小组开发,采用 vml + svg 绘图,使用了 Rapha ...

  7. 【转发】网易邮箱前端技术分享之javascript编码规范

    网易邮箱前端技术分享之javascript编码规范 发布日期:2013-11-26 10:06 来源:网易邮箱前端技术中心 作者:网易邮箱 点击:533 网易邮箱是国内最早使用ajax技术的邮箱.早在 ...

  8. web前端面试试题总结---javascript篇

    JavaScript 介绍js的基本数据类型. Undefined.Null.Boolean.Number.String. ECMAScript 2015 新增:Symbol(创建后独一无二且不可变的 ...

  9. iOS中动态注入JavaScript方法。动态给html标签添加事件

    项目中有这样一种需求,给html5网页中图片添加点击事件,并且弹出弹出点击的对应的图片,并且可以保持图片到本地 应对这样的需求你可能会想到很多方法来实现. 1. 最简单的方法就是在html5中添加图片 ...

随机推荐

  1. 【模拟】CF409C 【Magnum Opus】-C++

    题目背景 愚人节题目,题面似乎是一位名叫Nicolas Flamel的炼金术士用拉丁文写的某种物质的配方,结合谷歌尝试翻译了一下: 吾友: 哲人石所言不虚,人不可貌相,海不可斗量,唯努力得胜万象,亦无 ...

  2. 【译】深入理解G1的GC日志(一)

    本文翻译自:https://www.redhat.com/en/blog/collecting-and-reading-g1-garbage-collector-logs-part-2?source= ...

  3. 个人永久性免费-Excel催化剂功能第103波-批量打开多文件或多链接

    有时简单的东西,却带来许多的便利,为了让大家可以记住并容易找寻到此功能,也将这么简单的功能归为一波,反正已经100+波了,也无需为了凑功能文章而故意罗列一些小功能带忽悠性地让人觉得很强大. 使用场景 ...

  4. Excel催化剂开源第15波-VSTO开发之DataTable数据导出至单元格区域

    上篇提到如何从Excel界面上拿到用户的数据,另外反方向的怎样输出给用户数据,也是关键之处. VSTO最大的优势是,这双向的过程中,全程有用户的交互操作. 而一般IT型的程序,都是脱离用户的操作,只能 ...

  5. 题解 P3811 【【模板】乘法逆元】

    P3811 [模板]乘法逆元 一个刚学数论的萌新,总结了一下这题的大部分做法 //一.费马小定理+快速幂 O(nlogn) 64分 #include<cstdio> using names ...

  6. 关于Redis的几件小事 | 高并发和高可用

    如果你用redis缓存技术的话,肯定要考虑如何用redis来加多台机器,保证redis是高并发的,还有就是如何让Redis保证自己不是挂掉以后就直接死掉了. redis高并发:主从架构,一主多从,一般 ...

  7. APP爬虫(2)把小姐姐的图片down下来

    APP爬虫(1)想学新语言,又没有动力,怎么办? 书接上文.使用appium在帖子列表界面模拟上划动作,捕捉不到列表的规律.上划结束后,列表只能获取到屏幕呈现的部分,而且下标还是从0开始的. 根据酸奶 ...

  8. 数据库---T-SQL语句:查询语句(二)

    >查询: 一.查询所有数据: select * from Info    ---查询所有数据(行) select Name from Info  ---查询特定列(Name列) select N ...

  9. SpringBoot(18)---通过Lua脚本批量插入数据到Redis布隆过滤器

    通过Lua脚本批量插入数据到布隆过滤器 有关布隆过滤器的原理之前写过一篇博客: 算法(3)---布隆过滤器原理 在实际开发过程中经常会做的一步操作,就是判断当前的key是否存在. 那这篇博客主要分为三 ...

  10. GCD和扩展GCD

    gcd(a, b)用于求解自然数a,b的最大公约数 int gcd(int a, int b) { ) return a; return gcd(b, a%b); } extgcd(a, b, x, ...