当前位置: 首页 > news >正文

设计模式 -- 单例模式(传统面向对象与JavaScript 的对比实现)

单例模式 – 传统面向对象与JavaScript 的对比实现

文章目录

  • 单例模式 -- 传统面向对象与JavaScript 的对比实现
    • 传统的面向对象的实现
      • 定义
      • 实现思路
      • 初级实现
        • 缺点
      • 透明的单例模式实现
        • 目的(实现效果)
        • 实现
        • 缺点
      • 用代理实现单例模式
        • 优点
    • JavaScript 中的单例模式实现
      • 实现一:全局变量(不推荐)
        • 缺点
      • 实现二:惰性单例
        • 实现要点
        • JavaScript 的 最终实现
      • 应用场景

传统的面向对象的实现

定义

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

实现思路

用一个变量来标志当前是否已经为某个类创建过对象,如果是,则在下一次获取该类的实例时,直接返回之前创建的对象。

初级实现

		var Singleton = function (name) {this.name = name; this.instance = null;};Singleton.prototype.getName = function () {alert(this.name);};Singleton.getInstance = function (name) {if (!this.instance) {this.instance = new Singleton(name);}return this.instance;};const a = Singleton.getInstance('sven1'); const b = Singleton.getInstance('sven2');alert(a === b); // true

缺点

类的不透明性

通过 Singleton.getInstance 来获取 Singleton 类的唯一对象,这种方式相对简单,但有 一个问题,就是增加了这个类的“不透明性”,Singleton 类的使用者必须知道这是一个单例类, 跟以往通过 new XXX 的方式来获取对象不同,这里偏要使用 Singleton.getInstance 来获取对象。


透明的单例模式实现

目的(实现效果)

我们现在的目标是实现一个“透明”的单例类,用户从这个类中创建对象的时候,可以像使 用其他任何普通类一样。


实现

		const Singleton = (function (name) {let instance;function createDiv(name) {if (instance) {return instance;}this.name = name;this.init();return instance = this;}createDiv.prototype.init = function () {const div = document.createElement('div');div.innerHTML = this.name;document.body.appendChild(div);}return createDiv;})();const a = new Singleton('sven1');const b = new Singleton('sven2');

缺点

  1. 为了把 instance 封装起来,我们使用了自执行的匿名函数和闭包,并且让这个匿名函数返回真正的 Singleton 构造方法,这增加了一些程序的复杂度,阅读起来也不是很舒服。
  2. 不符合单一职责,不利于维护。构造函数实际上负责了两件事情。第一是创建对象和执行初始化 init 方法,第二是保证只有一个对象。

用代理实现单例模式

		const CreateDiv = function (name) {this.name = name;this.init();}CreateDiv.prototype.init = function () {const div = document.createElement('div');div.innerHTML = this.name;document.body.appendChild(div);};const ProxySingletonCreateDiv = (function () {let instance;return function (name) {if (!instance) {instance = new CreateDiv(name);}return instance;}})();const a = new ProxySingletonCreateDiv('seven1');const b = new ProxySingletonCreateDiv('seven2');alert(a === b);

优点

跟之前不同的是,现在我们把负责管理单例的逻辑移到了代理类 proxySingletonCreateDiv 中。这样一来,CreateDiv 就变成了 一个普通的类,它跟 proxySingletonCreateDiv 组合起来可以达到单例模式的效果。


JavaScript 中的单例模式实现

以上提到的几种单例模式的实现,更多的是接近传统面向对象语言中的实现,单例对象从 “类”中创建而来。在以类为中心的语言中,这是很自然的做法。比如在 Java 中,如果需要某个对象,就必须先定义一个类,对象总是从类中创建而来的。
但 JavaScript 其实是一门无类(class-free)语言

单例模式的核心是确保只有一个实例,并提供全局访问。


实现一:全局变量(不推荐)

如果 a 变量被声明在全局作用域下, 则我们可以在代码中的任何位置使用这个变量,全局变量提供给全局访问是理所当然的。这样就 满足了单例模式的两个条件。

缺点

全局变量存在很多问题,它很容易造成命名空间污染


实现二:惰性单例

惰性单例指的是在需要的时候才创建对象实例
如 上面初级实现中 instance 实例对象总是在我们调用 Singleton.getInstance 的时候才被创建,而不是在页面加载好 的时候就创建

实现要点

  1. 使用惰性单例:需要的时候才创建
  2. 把不变的部分隔离出来。先不考虑创建一个 div 和创建一个 iframe 有多少差异,抽离管理单例的逻辑,这个逻辑始终是一样的: 用一个变量来标志是否创建过对象,如果是,则在下次直接返回这个已经创建好的对象:

JavaScript 的 最终实现

		var getSingle = function (fn) {var result;return function () {return result || (result = fn.apply(this, arguments));}};var createSingleIframe = getSingle(function () {var iframe = document.createElement('iframe');document.body.appendChild(iframe);return iframe; 6});document.getElementById('loginBtn').onclick = function () {var loginLayer = createSingleIframe();loginLayer.src = 'http://baidu.com';};

把创建实例对象的职责和管理单例的职责分别放置在两个方法里,这两 个方法可以独立变化而互不影响,当它们连接在一起的时候,就完成了创建唯一实例对象的功能。


应用场景

  • 线程池、全局缓存、浏览器中的 window 对象等
  • 创建单一实例

参考文献:
JavaScript 设计模式与开发实践 (by 曾探)

相关文章:

设计模式 -- 单例模式(传统面向对象与JavaScript 的对比实现)

单例模式 – 传统面向对象与JavaScript 的对比实现 文章目录 单例模式 -- 传统面向对象与JavaScript 的对比实现传统的面向对象的实现定义实现思路初级实现缺点 透明的单例模式实现目的(实现效果)实现缺点 用代理实现单例模式优点 JavaScript 中的单例模…...

YOLOX算法调试记录

YOLOX是在YOLOv3基础上改进而来,具有与YOLOv5相媲美的性能,其模型结构如下: 由于博主只是要用YOLOX做对比试验,因此并不需要对模型的结构太过了解。 先前博主调试过YOLOv5,YOLOv7,YOLOv8,相比而言,YOLOX的环…...

基于小程序的汽车俱乐部系统的设计与实现(论文+源码)_kaic

目录 前 言 1 系统概述 1.1 系统主要功能 1.2 开发及运行环境 2 系统分析和总体设计 2.1 需求分析 2.2 可行性分析 2.3 设计目标 2.4 项目规划 2.5 系统开发语言简介 2.6 系统功能模块图 3 系统数据库设计 3.1 数据库开发工具简介 3.2 数据库需求分析 3.3 数据库…...

ProgrammingArduino物联网

programming_arduino_ed2 IO 延时闪灯 void setup() {pinMode(13, OUTPUT); }void loop() {digitalWrite(13, HIGH);delay(500);digitalWrite(13, LOW);delay(500); }// sketch 03-02 加入变量 int ledPin 13; int delayPeriod 500;void setup() {pinMode(ledPin, OUTPUT)…...

SSM框架的学习与应用(Spring + Spring MVC + MyBatis)-Java EE企业级应用开发学习记录(第一天)Mybatis的学习

SSM框架的学习与应用(Spring Spring MVC MyBatis)-Java EE企业级应用开发学习记录(第一天)Mybatis的学习 一、当前的主流框架介绍(这就是后期我会发出来的框架学习) Spring框架 ​ Spring是一个开源框架,是为了解决企业应用程序开发复杂…...

Programming abstractions in C阅读笔记: p118-p122

《Programming Abstractions In C》学习第49天,p118-p122,总结如下: 一、技术总结 1.随机数 (1)seed p119,“The initial value–the value that is used to get the entire process start–is call a seed for the random ge…...

2023国赛数学建模思路 - 案例:ID3-决策树分类算法

文章目录 0 赛题思路1 算法介绍2 FP树表示法3 构建FP树4 实现代码 建模资料 0 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 1 算法介绍 FP-Tree算法全称是FrequentPattern Tree算法,就是频繁模…...

selenium 选定ul-li下拉选项中某个指定选项

场景:selenium的下拉选项是ul-li模式,选定某个指定的选项。 from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC # 显示等待def select_li(self, text, *ul_locator):"…...

回归预测 | MATLAB实现FA-SVM萤火虫算法优化支持向量机多输入单输出回归预测(多指标,多图)

回归预测 | MATLAB实现FA-SVM萤火虫算法优化支持向量机多输入单输出回归预测(多指标,多图) 目录 回归预测 | MATLAB实现FA-SVM萤火虫算法优化支持向量机多输入单输出回归预测(多指标,多图)效果一览基本介绍…...

使用pytorch 的Transformer进行中英文翻译训练

下面是一个使用torch.nn.Transformer进行序列到序列(Sequence-to-Sequence)的机器翻译任务的示例代码,包括数据加载、模型搭建和训练过程。 import torch import torch.nn as nn from torch.nn import Transformer from torch.utils.data im…...

解决element的select组件创建新的选项可多选且opitions数据源中有数据的情况下,回车不能自动选中创建的问题

前言 最近开发项目使用element-plus库内的select组件,其中有提供一个创建新的选项的用法,但是发现一些小问题,在此记录 版本 “element-plus”: “^2.3.9”, “vue”: “^3.3.4”, 问题 1、在options数据源中无数据的时候,在输入框…...

人工智能大模型加速数据库存储模型发展 行列混合存储下的破局

数据存储模型 ​专栏内容: postgresql内核源码分析手写数据库toadb并发编程toadb开源库 个人主页:我的主页 座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物. 概述 在数据库的发展过程中,关…...

K8S用户管理体系介绍

1 K8S账户体系介绍 在k8s中,有两类用户,service account和user,我们可以通过创建role或clusterrole,再将账户和role或clusterrole进行绑定来给账号赋予权限,实现权限控制,两类账户的作用如下。 server acc…...

实现chatGPT 聊天样式

效果图 代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Chat Example</title&g…...

day9 STM32 I2C总线通信

I2C总线简介 I2C总线介绍 I2C&#xff08;Inter-Integrated Circuit&#xff09;总线&#xff08;也称IIC或I2C&#xff09;是由PHILIPS公司开发的两线式串行总线&#xff0c;用于连接微控制器及其外围设备&#xff0c;是微电子通信控制领域广泛采用的一种总线标准。 它是同步通…...

终极Shell:Zsh(CentOS7 安装 zsh 及 配置 Oh my zsh)

CentOS7 安装 zsh 及 配置 Oh my zsh 我们在通过Shell操作linux终端时&#xff0c;配置、颜色区分、命令提示大都达不到我们预期的效果或者操作较为繁琐。 今天就来介绍一款终极一个及其好用的类Linux系统中的终端软件,江湖称之为马车中的跑车,跑车中的飞行车,史称『终极 Shell…...

Redis的数据持久化

前言 本文主要介绍Redis的三种持久化方式、AOF持久化策略等 什么是持久化 持久化是指将数据在内存中的状态保存到非易失性介质&#xff08;如硬盘、固态硬盘等&#xff09;上的过程。在计算机中&#xff0c;内存中的数据属于易失性数据&#xff0c;一旦断电或重启系统&#…...

CSS 选择器

前言 基础选择器 以下是几种常见的基础选择器。 标签选择器&#xff1a;通过HTML标签名称选择元素。 例如&#xff1a; p {color: red; } 上述样式规则将选择所有<p>标签 &#xff0c;并将其文字颜色设置为红色。 类选择器&#xff1a;通过类名选择元素。使用类选择…...

上位机工作总结(2023.03-2023.08)

1.工作总结 不知不觉&#xff0c;已经从C#转为Qt开发快半年了。这半年内&#xff0c;也是学习了很多C相关的开发技能&#xff0c;同时自己的技术栈也是进一步丰富&#xff0c;以后跑路就更容易啦&#xff0c;哈哈&#xff01;自己之前就有Winform和一些简单的Qt项目实践&#…...

APSIM模型参数优化 批量模拟丨气象数据准备、物候发育和光合生产、物质分配与产量模拟、土壤水分平衡算法、土壤碳氮平衡模块、农田管理模块等

随着数字农业和智慧农业的发展&#xff0c;基于过程的农业生产系统模型在模拟作物对气候变化的响应与适应、农田管理优化、作物品种和株型筛选、农田固碳和温室气体排放等领域扮演着越来越重要的作用。APSIM (Agricultural Production Systems sIMulator)模型是世界知名的作物生…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

《通信之道——从微积分到 5G》读书总结

第1章 绪 论 1.1 这是一本什么样的书 通信技术&#xff0c;说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号&#xff08;调制&#xff09; 把信息从信号中抽取出来&am…...

现代密码学 | 椭圆曲线密码学—附py代码

Elliptic Curve Cryptography 椭圆曲线密码学&#xff08;ECC&#xff09;是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础&#xff0c;例如椭圆曲线数字签…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)

Aspose.PDF 限制绕过方案&#xff1a;Java 字节码技术实战分享&#xff08;仅供学习&#xff09; 一、Aspose.PDF 简介二、说明&#xff08;⚠️仅供学习与研究使用&#xff09;三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)

漏洞概览 漏洞名称&#xff1a;Apache Flink REST API 任意文件读取漏洞CVE编号&#xff1a;CVE-2020-17519CVSS评分&#xff1a;7.5影响版本&#xff1a;Apache Flink 1.11.0、1.11.1、1.11.2修复版本&#xff1a;≥ 1.11.3 或 ≥ 1.12.0漏洞类型&#xff1a;路径遍历&#x…...

免费数学几何作图web平台

光锐软件免费数学工具&#xff0c;maths,数学制图&#xff0c;数学作图&#xff0c;几何作图&#xff0c;几何&#xff0c;AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...

用鸿蒙HarmonyOS5实现中国象棋小游戏的过程

下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...

MySQL的pymysql操作

本章是MySQL的最后一章&#xff0c;MySQL到此完结&#xff0c;下一站Hadoop&#xff01;&#xff01;&#xff01; 这章很简单&#xff0c;完整代码在最后&#xff0c;详细讲解之前python课程里面也有&#xff0c;感兴趣的可以往前找一下 一、查询操作 我们需要打开pycharm …...

阿里云Ubuntu 22.04 64位搭建Flask流程(亲测)

cd /home 进入home盘 安装虚拟环境&#xff1a; 1、安装virtualenv pip install virtualenv 2.创建新的虚拟环境&#xff1a; virtualenv myenv 3、激活虚拟环境&#xff08;激活环境可以在当前环境下安装包&#xff09; source myenv/bin/activate 此时&#xff0c;终端…...