简述4种设计模式(模块设计模式 原型模式 观察者模式 单例模式)

1 前言
每个JS开发者都力求写出可维护、复用性和可读性高的代码。随着应用不断扩大,代码组织的合理性也越来越重要。设计模式为特定环境下的常见问题提供了一个组织结构,对于克服这些挑战起到至关重要的作用。
JavaScript 网页开发者在创建应用时,频繁地跟设计模式打交道(甚至在不知情的情况下)。
尽管特定环境下有各种各样的设计模式,JS 开发者还是倾向于使用一些习惯性的模式。
在这篇文章中,我将讨论这些常见的设计模式,展出优化代码库的方法,并深入解读JavaScript的内部构件。本文讨论的设计模式包括这几种:
模块设计模式
原型模式
观察者模式
单例模式
2 模式说明
设计模式

  • 什么是设计模式?
    => 针对 特定问题, 给出的简洁而优化的处理方案
  • 一个设计模式 A
    => 只能解决 A 类型的问题
    => 针对 B 类型的问题, 设计模式 A 解决不了
  • 同一个问题, 再不同的位置, 是不一定能用同一种方案解决
  • 设计模式, 只在特定的情况, 特定的时期, 针对特定的问题使用

市场上常用的设计模式

  • 单例模式
  • 组合模式
  • 观察者模式
  • 适配器模式
  • 代理模式
  • 工厂模式
  • 构建模式

单例模式

  • 单: 单一, 一个, 独个
  • 例: 实例(构造函数的实例化对象)
  • 让一个构造函数一辈子只有一个实例对象
    => 当你需要一个构造函数一生只能 new 出一个对象的时候
    => 就可以使用单例模式
    单例模式的简单应用
  • 弹出层 alert() 比较丑, 用户体验极度不好
  • 好多网站会使用一个自己写的 div 盒子, 当作弹出层
  • 再自己写的过程中, 一个网站不可能只弹出一次
    => 不能每次弹出就创建一个 div
    => 每次弹出的都是之前创造好的那个 div, 只是文字改变了
  • 创造 div 并显示出来的构造函数
    => 如果不用单例模式, 每次 new 就是创造一个 div
    => 如果用了单例模式, 每次 new 都是用的第一次的 div, 只是改变文字内容
    自执行函数
  • 一个正常的函数是定义完毕以后需要调用
  • 自执行函数, 就是把函数当成一个表达式, 在定义完毕以后直接就调用了
  • 自己的语法格式
  1. (function () {})()
  2. ~function () {}()
  3. !function () {}()
  • 以上三种没有任何区别, 只是语法格式不一样而已

fn()()

  • fn调用一次, 然后把 fn 的返回值再调用一次
  • 前提: fn 的返回值必须是一个函数, 不然就报错了
    (function () {})()
  • 自执行函数
  • 前面一个括号里面写的必须是一个函数表达式, 不然就报错了

构造函数使用需要和 new 连用

  • 构造函数体内如果 return 了一个基本数据类型, 写了白写
    => new 连用的时候, 得不到你 return 的基本数据类型
  • 构造函数体内如果 return 了一个复杂数据类型, 构造函数白写
    => 写不写 new, 得到的都是 return 的 复杂数据类型

组合模式

  • 米家:
    => 当你回家的时候, 你一打开门
    => 家里的所有东西就启动了, 灯会亮起来, 电视打开了, 空调打开了, 窗帘拉开了, …
  • 组合模式:
    => 把我们若干这启动方式一样的构造函数放在一起
    => 准备一个总开关, 总开关一启动, 那么这些个构造函数就都启动了

实现组合模式:

  • 需要一个承载所有构造函数实例的数组
  • 需要一个方法, 向数组里面添加内容
  • 需要一个方法, 能把数组里面的所有内容启动了

常见应用场景

  • 轮播图:
    => 基础版本的轮播图依靠定时器再左右移动
    => 一旦我切换页面以后, DOM 不动, 定时器在动, 等你再切换回来页面的时候就出问题了
    => 当我离开当前页面的时候, 应该关闭定时器
    => 等我再次回到当前页面的时候, 应该再从新启动定时器
    => 一个页面只有一个轮播图, 那么没有问题
    => 一旦一个页面多个轮播图的时候, 我们就可以整一个组合模式
  • 做一个总开关
    => 离开页面的时候, 所有的轮播图都停止定时器
  • 再来一个总开关
    => 回到页面的时候, 所有的轮播图再次启动

观察者模式

  • 又称 发布/订阅 模式
  • 目前市场上的开发人员, 分成两派人员
    => 一派人, 认为 观察者 和 发布/订阅 是一个设计模式
    => 一派人, 认为 观察者 和 发布/订阅 是两个设计模式
  • 两派人到现在也没有定论
    => 目前还在互相想说服对方
  • 我们的 PPT 制作的时候, 倾向于 发布/订阅 制作的
    => 个人认为是两个事情, 所以我给你们讲两个
    => 一个从 观察者 角度出发
    => 一个从 发布/订阅 角度出发

观察者角度(这两个是一个东西)

  • 就像我们小时候的班主任一样
    => 班主任, 年级主任, 教务主任, 都有一个共同的能力叫做 请家长
    => 他们就是暗中观察我们的人, 一旦我们做的事情和他们想的不一样, 就回触发技能
    => 他们就是观察者, 当被观察者一旦出现变化, 立马触发他们的技能
  • 被观察者
    => 就是一个学生, 你的状态就应该是 好好学习
    => 一旦你的状态改变为 玩手机
    => 立马就会通知正在观察着你的人, 观察着你的人, 就会触发技能
  • 目的:
    => 让 观察者 看着 被观察者, 只要数据改变了
    => 就让 观察者 做一些事情

发布/订阅 角度

  • 分成三个状态
    => 订阅
    => 取消订阅
    => 发布
  • 例子: 买书
    => 我想买一本 《JavaScript 从入门到放弃》
    => 去到书店买, 如果书店没有
    => 那么我就要回家, 第二天再来看
    => 还没有, 再回家, 第三天再来看
    => 直到书店里面有了这个书, 我就买走
  • 发布/订阅 的时候
    => 我想买一本 《如何治疗颈椎病》
    => 我去到书店买, 如果书店没有
    => 我就和店员说一下, 等有了你给我打电话 -> 订阅 事件
    => 我就踏实的在家等着, 等电话
    => 一旦书店到了这本书, 就会给我打电话了 -> 由店员 发布 事件
    => 再中间时间的时候, 我的朋友送了我一本这个书
    => 我就告诉店员, 你来了这个书也不需要给我打电话了 -> 取消 订阅 事件
    => 我已经由了, 不需要你在告诉我了
  • js 里面由实际应用
    => addEventListener(‘click’, fn)
    => 当 click 行为触发的时候, 就会执行 fn 函数
    => 还可以绑定多个事件处理函数 (就是由好多人可以向店员订阅事件, 书到了告诉我)
    => 当 click 行为触发的时候, 所有的事件处理函数 都会执行
  • 做的事情
    => 就是模仿 addEventListener 自己做一个事件监听

发布/订阅 需要的内容

  1. 消息盒子 {}
    => click: [fn1, fn2, fn3]
    => mouseover: [fn4, fn5, fn6]
  2. 订阅的方法
    => 向消息盒子里面添加内容
  3. 取消订阅的方法
    => 把已经订阅的方法从消息盒子内部拿走
  4. 发布事件的方法
    => 把消息盒子里面的对应的处理函数执行了

3 总结
设计模式经常用于比较大型的应用,想知道哪种模式更具优势,来实践吧。
在构建任何应用之前,都应该全面地考虑每个角色,以及它们之间存在的关系。在回顾 模块模式、原型模式、观察者模式 和 单例模式 之后,你应该能够区分它们,并且在实际开发中使用它们了。

你可能感兴趣的:(简述4种设计模式(模块设计模式 原型模式 观察者模式 单例模式))