精读《设计模式 - Singleton 单例模式》

2023-05-16

Singleton(单例模式)

Singleton(单例模式)属于创建型模式,提供一种对象获取方式,保证在一定范围内是唯一的。

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

其实单例模式在前端体会的不明显,原因有:

  1. 前端代码本身在单机运行,创建的任何变量都是天然分布式的,不需要担心影响另一个用户。

  2. 后端代码是一对多的,分辨出哪些资源是请求间共享的,哪些是请求内独有的很重要。

另外我们说到单例,是隐含了一个范围的,指的是在某个范围内单例,比如在一个上下文中,还是一个房间中,还是一个进程,一个线程中单例,不同场景范围会不同。

举例子

如果看不懂上面的意图介绍,没有关系,设计模式需要在日常工作里用起来,结合例子可以加深你的理解,下面我准备了三个例子,让你体会什么场景下会用到这种设计模式。

多人游戏的共享物品

玩过游戏的同学都知道,我们在每局游戏中使用的公共物品在当前房间中是唯一的,但在游戏房间间却不是唯一的,所以这些公共物品肯定有不同的类去描述,那每局游戏中怎么拿公共物品,可以保证拿到的是当前局内唯一的?

Redux 数据流

其实前端的 Redux 数据流本身就是单例模式,在一个应用中,数据是唯一的,但可以有不同的 UI 使用这份唯一的数据,甚至把一个表格组件展示在两个不同地方,比如全屏模式,但数据依然是一份,我们没有必要为了全屏展示表格,就让它再发一次取数请求,完全可以和原来的表格共享一份数据。

数据库连接池

每个 SQL 查询都依赖数据库连接池,如果每次查询都建立一次数据库连接池,则建立连接的速度会远远慢于 SQL 查询速度,因此你会怎么设计数据库连接池的获取方法?

意图解释

单例模式的意图很简单,几乎就是其字面含义:

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

对于多人游戏的共享物品,比如一口锅,要保证在一局游戏内唯一,就要提供一种方法访问到唯一实例。

Redux 数据流的 connect 装饰器就是全局访问点的一种设计。

数据库连接池可以提前初始化好,并通过固定 API 提供这个唯一实例。

结构图

Singleton 是单例模式的接口,客户只能通过其定义的 instance() 访问实例,以保证单例。

代码例子

下面例子使用 typescript 编写。

class Ball {
  private _instance = undefined

  // 构造函数申明为 private,就可以阻止 new Ball() 行为
  private constructor() {}

  public static instance = () => {
    if (this._instance === undefined) {
      this._instance = new Ball()
    }

    return this._instance
  }
}

// 使用
const ball = Ball.getInstance()

可以仔细想想,为什么这个例子把单例写成了静态方法,而不是一个全局变量?其实全局变量也能解决问题,但由于会污染全局,要尽可能通过模块化方式解决,上面的例子就是一个较好的封装方式。

当然这只是一个最简单的例子,实际上单例模式还有几种模式:

饿汉式

初始化时就生成一份实例,这样调用时直接就能获取。

懒汉式

就是代码例子中写的,按需实例化,即调用的时候再实例化。

要注意,按需不一定是什么好事,如果 New 的成本很高还按需实例化,可能把系统异常的风险留到随机的触发时机,导致难以排查 BUG,另外也会影响第一次实例化时的系统耗时。

对 JAVA 来说,单例还需要考虑并发性,有 双重检测、静态内部类、枚举 等办法解决,这里不具体展开。

弊端

单例模式的问题有:

  • 对面向对象不太友好。对封装、继承、多态支持不够友好。

  • 不利于梳理类之间的依赖关系。毕竟单例是直接调用的,而不是在构造函数申明的,所以要梳理关系要看完每一行代码才能确定。

  • 可拓展性不好。万一要支持多例就比较难拓展,比如全局数据流可能因为微前端方案改成多实例、数据库连接池为了分治 SQL 改成多实例,都是有可能的,在系统设计之初就要考虑到未来是否还会保持单例。

  • 可测试性不好,因为单例是全局共享的,无法保证测试用例间的隔离。

  • 无法使用构造函数传参。

另外单例模式还可以被工厂方法所替代,所以不用特别纠结一种设计模式,可以结合使用,工厂函数也可以内嵌单例模式。

总结

单例模式概念、用法都简单,是架构设计常用方案,但要充分理解到单例模式的弊端,防止不恰当的使用。

讨论地址是:精读《设计模式 - Singleton 单例模式》· Issue #278 · dt-fe/weekly

如果你想参与讨论,请 点击这里,每周都有新的主题,周末或周一发布。前端精读 - 帮你筛选靠谱的内容。

关注 前端精读微信公众号

版权声明:自由转载-非商用-非衍生-保持署名(创意共享 3.0 许可证)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

精读《设计模式 - Singleton 单例模式》 的相关文章

  • Day-1(爬虫的基础,环境配置)

    这是我做的第一个带有前端的爬虫项目 xff0c 自己的构想是 爬虫使用scrapy框架 xff0c 前端使用django框架 xff0c 开发工具使用pycharm xff0c 开发环境使用python3 7 xff0c 主要任务 xff1
  • Day-2实现django框架的前端界面

    我们昨天已经将本次项目的基础环境搭建完成 xff0c 今天我们需要将我们的django框架的前端界面部分完成 任务 xff1a 书城的界面 一 创建django项目 首先在cmd格式下输入 django admin startproject
  • django2.2/mysql ImproperlyConfigured: mysqlclient 1.3.13 or newer is required; you have 0.9.3

    django2 2 mysql ImproperlyConfigured mysqlclient 1 3 13 or newer is required you have 0 9 3 这个是我昨天的在做项目的时候 xff0c 遇见的一个问题
  • Day-3页面分析(Xpath)

    一 爬取分析 爬虫是非常考验随机性的 xff0c 运气性 xff0c 以及思维跳跃的 在此次项目中 xff0c 首先我们找到京东图书的页面 xff0c 进入到里边 京东所有图书的API接口是 xff1a http book jd com b
  • Centos7 环境配置安装boost库与mpich库

    Centos7 环境配置 一 安装mpich3 2 参考博客 xff1a https blog csdn net zhaohaibo article details 87197138 安装依赖 yum install y make gcc
  • Clion安装以及配置本地C++环境

    一 下载Clion 去JB公司官网下载CLion https www jetbrains com clion download section 61 windows 然后就是等 xff0c 一直等 xff0c 不要运行 xff0c 等到mi
  • 7-2国王游戏

    题目 xff1a 恰逢 H 国国庆 xff0c 国王邀请 n 位大臣来玩一个有奖游戏 首先 xff0c 他让每个大臣在左 右手上面分别写下一个整数 xff0c 国王自己也在左 右手上各写一个整数 然后 xff0c 让这 n 位大臣排成一排
  • 编码

    编码 Time Limit 1000MS Memory Limit 65536KB Problem Description 给你一个由大写字母组成的组成的字符串 xff0c 你可以用如下规则对其进行编码 xff1a 1 包含K个相同字母的连
  • C语言实验——字符编码

    C语言实验 字符编码 Time Limit 1000MS Memory Limit 65536KB Problem Description 请将一串长度为5的纯字母文本译成一个密码 xff0c 密码规律如下 xff1a 用原来的字母后面的第
  • C语言实验——求一个3*3矩阵对角线元素之和

    C语言实验 求一个3 3矩阵对角线元素之和 Time Limit 1000MS Memory Limit 65536KB Problem Description 给定一个3 3的矩阵 xff0c 请你求出对角线元素之和 Input 按照行优
  • 爬山

    爬山 Time Limit 1000MS Memory Limit 65536KB Problem Description LeiQ最近参加了一个登山俱乐部 xff0c 部长给他了一个n m地图 地图上的每一个格子的值表示一个山的海拔高度
  • 鞍点计算

    鞍点计算 Time Limit 1000MS Memory Limit 65536KB Problem Description 找出具有m行n列二维数组Array的 鞍点 xff0c 即该位置上的元素在该行上最大 xff0c 在该列上最小
  • 回文串判定

    回文串判定 Time Limit 1000MS Memory Limit 65536KB Problem Description 输入一串字符 xff08 长度小于100 xff09 xff0c 判断该串字符是否是回文串 xff08 正序读
  • C语言合法标识符

    C语言合法标识符 Time Limit 1000MS Memory Limit 65536KB Problem Description 输入一个字符串 xff0c 判断其是否是C的合法标识符 Input 输入数据包含多个测试实例 xff0c
  • 简单字符串排序

    简单字符串排序 Time Limit 5000MS Memory Limit 100000KB Problem Description 从键盘输入10个学生的姓名和成绩 xff0c 请按字典序排列学生的姓名并输出 xff08 姓名和成绩对应
  • 小鑫の日常系列故事(二)——石头剪子布

    小鑫 日常系列故事 xff08 二 xff09 石头剪子布 Time Limit 1000MS Memory Limit 65536KB 小鑫在上幼儿园的时候 xff0c 喜欢跟小伙伴健健玩石头剪子布的游戏 xff0c 你能帮他们判断谁胜谁
  • 中位数

    中位数 Problem Description 中位数是指在一组数据中 xff0c 按数值大小排序后处于中间位置的数 例如 xff1a 1 5 3 排序后为 1 3 5 xff0c 则其中位数为 3 特别地 xff0c 当数的个数 N 为偶
  • 分享下我 Github 被封的经历

    最近好像又有人 Github 被封 xff0c 每隔一段时间就有 分享下我自己的经历吧 xff0c 好几年以前了 xff0c 也许还是有点参考价值 账号被封 xff0c 查找原因 那是 2017 年 12 月 xff0c 有天早上起来突然发
  • 幸运数字

    幸运数字 Time Limit 1000MS Memory Limit 65536KB Problem Description 我们定义幸运数字为只含有且必须同时含有 4 和 7 的数 例如 xff1a 47 747 是幸运数字 xff0c
  • A-B Problem

    A B Problem Time Limit 1000MS Memory Limit 65536KB Problem Description 这次当然不是简单的 a b 呐 xff5e 有一个神奇的变换规则是这样的 xff1a 给定两个数

随机推荐

  • C语言实验——一元二次方程Ⅰ

    C语言实验 一元二次方程 Time Limit 1000MS Memory Limit 65536KB Problem Description 解一元二次方程ax 2 43 bx 43 c 61 0的解 保证有解 Input a b c的值
  • C/C++经典程序训练2---斐波那契数列

    C C 43 43 经典程序训练2 斐波那契数列 Time Limit 1000MS Memory Limit 65536KB Problem Description 编写计算斐波那契 xff08 Fibonacci xff09 数列的第n
  • C/C++程序训练6---歌德巴赫猜想的证明

    C C 43 43 程序训练6 歌德巴赫猜想的证明 Time Limit 1000MS Memory Limit 65536KB Problem Description 验证 每个不小于6的偶数都是两个素数之和 xff0c 输入一个不小于6
  • C语言实验——整数位

    C语言实验 整数位 Time Limit 1000MS Memory Limit 65536KB Problem Description 输入一个不多于5位的正整数 xff0c 要求 xff1a xff08 1 xff09 求出它是几位数
  • C语言实验——各位数字之和排序

    C语言实验 各位数字之和排序 Time Limit 1000MS Memory Limit 65536KB Problem Description 给定n个正整数 xff0c 根据各位数字之和从小到大进行排序 Input 输入数据有多组 x
  • yxc 的日常

    yxc 的日常 Time Limit 1000MS Memory Limit 65536KB Problem Description yxc 特别喜欢睡觉 xff0c 但是由于上课和训练 xff0c 他睡觉的时间并不是连续的 xff0c 他
  • 奇偶性

    奇偶性 Time Limit 1000MS Memory Limit 32768KB Problem Description 判断输入的数据的奇偶性 Input 输入数据第一行是一个正整数N 接下来N行 xff0c 每行一个正整数 Outp
  • 念数字

    山东理工大学第一届团体程序设计天梯赛各班内组队选拔测试赛 3 290 分 编程题共 15 小题 xff0c 共计 290 分 剩余时间 30 03 10 剩余时间 30 03 10 编程题 7 9 念数字 xff08 15 分 xff09
  • Linux环境Ubuntu版本安装CMake V3.23.1记录

    以下采用源码方式安装 xff0c 先确认Ubuntu能够正常访问网络 以下bash终端命令皆是在root权限下 xff0c 否则在命令前加sudo 官方网址 xff1a 跳转连接 在命令终端切换root权限后 xff0c 安装以下内容 ni
  • 数据结构实验之链表二:逆序建立链表

    Problem Description 输入整数个数N xff0c 再输入N个整数 xff0c 按照这些整数输入的相反顺序建立单链表 xff0c 并依次遍历输出单链表的数据 Input 第一行输入整数N xff1b 第二行依次输入N个整数
  • 数据结构实验之链表一:顺序建立链表

    Problem Description 输入N个整数 xff0c 按照输入的顺序建立单链表存储 xff0c 并遍历所建立的单链表 xff0c 输出这些数据 Input 第一行输入整数的个数N xff1b 第二行依次输入每个整数 Output
  • 数据结构实验之链表七:单链表中重复元素的删除

    书上的例题 Problem Description 按照数据输入的相反顺序 xff08 逆位序 xff09 建立一个单链表 xff0c 并将单链表中重复的元素删除 xff08 值相同的元素只保留最后输入的一个 xff09 Input 第一行
  • 数据结构实验之链表九:双向链表

    数据结构实验之链表九 xff1a 双向链表 Time Limit 1000 ms Memory Limit 65536 KiB Problem Description 学会了单向链表 xff0c 我们又多了一种解决问题的能力 xff0c 单
  • 数据结构实验之排序八:快速排序

    数据结构实验之排序八 xff1a 快速排序 Time Limit 1000 ms Memory Limit 65536 KiB Submit Statistic Problem Description 给定N N 10 5 个整数 xff0
  • 养兔子

    养兔子 Time Limit 1000 ms Memory Limit 65536 KiB Submit Statistic Problem Description 一对成熟的兔子每天能且只能产下一对小兔子 xff0c 每次都生一公一母 x
  • 母牛的故事

    母牛的故事 Time Limit 1000 ms Memory Limit 65536 KiB Submit Statistic Problem Description 有一对夫妇买了一头母牛 xff0c 它从第2年起每年年初生一头小母牛
  • 猴子分桃

    猴子分桃 Time Limit 1000 ms Memory Limit 65536 KiB Submit Statistic Problem Description 老猴子辛苦了一辈子 xff0c 给那群小猴子们留下了一笔巨大的财富 一大
  • 骨牌铺方格

    骨牌铺方格 Time Limit 1000 ms Memory Limit 32768 KiB Submit Statistic Problem Description 在2 n的一个长方形方格中 用一个1 2的骨牌铺满方格 输入n 输出铺
  • 三国佚事——巴蜀之危

    三国佚事 巴蜀之危 Time Limit 1000 ms Memory Limit 65536 KiB Submit Statistic Problem Description 话说天下大势 xff0c 分久必合 xff0c 合久必分 却道
  • 精读《设计模式 - Singleton 单例模式》

    Singleton xff08 单例模式 xff09 Singleton xff08 单例模式 xff09 属于创建型模式 xff0c 提供一种对象获取方式 xff0c 保证在一定范围内是唯一的 意图 xff1a 保证一个类仅有一个实例 x