首页 > 其他分享 >前端开发设计模式: 单例模式

前端开发设计模式: 单例模式

时间:2024-10-30 18:42:00浏览次数:1  
标签:对象 模式 instance 实例 单例 全局 设计模式 前端开发

什么是单例模式?(Singleton Pattern) 

单例模式,也叫单体模式,是一种创建型设计模式,是全局(或某一作用域范围)唯一实例,大家共享、复用一个实例对象。—— 最基础、最常见的设计模式

1、保证对象实例只创建一次,后续的引用都是同一个实例对象
2、保证一个类只有一个实例,并提供一个访问它的 全局访问点

 

单例模式特点:

  • 唯一性:只有一个实例,无论在程序的任何地方访问这个类,都将得到同一个实例
  • 全局访问:提供了一种全局访问该实例的方式,使得在整个程序中都可以方便地使用这个唯一的实例

 

为什么要用单例模式?

单例模式的优点

  1、减少资源消耗:

    对于一些需要频繁创建但又只需一个实例的对象,如全局状态管理、日志记录器等,使用单例模式可以避免重复创建对象带来的资源浪费和性能问题

  2、全局访问

    提供了一个简单的方式来访问唯一的实例,方便在不同的模块中使用

  3、易于管理

    由于只有一个实例,对于一些需要统一管理的对象,如配置对象、全局缓存等,使用单例模式可以方便地进行管理和维护。

 

单例模式的缺点

  1、测试困难

    由于单例通常是全局可访问的,这使得在单元测试中难以模拟和控制其行为,可能会导致测试的复杂性增加

  2、违法单一职责原则

    单例对象可能承担过多的职责,不利于代码的可维护性和扩展性

  3、可能导致内存泄漏

    如果单例对象在整个应用的生命周期中都存在,并且持有一些资源(如数据库连接、文件句柄等),如果不及时释放这些资源,可能会导致内存泄漏

 

单例模式的应用场景

  1、全局状态管理

    在前端应用中,可能需要一个全局的状态管理器来存储和管理应用的状态。使用单例模式可以确保只有一个状态管理器实例,避免状态的混乱和不一致。

  2、日志记录器

    日志记录器通常需要在整个应用中共享,以便在不同的地方记录日志。使用单例模式可以确保只有一个日志记录器实例,方便进行日志的统一管理和输出。

    例如,可以创建一个单例的日志记录器对象,提供方法来记录不同级别的日志信息,并将日志输出到控制台或文件中。

  3、数据库连接

    在与数据库进行交互时,通常需要建立数据库连接。使用单例模式可以确保只有一个数据库连接实例,避免重复建立连接带来的资源浪费和性能问题。

    例如,可以创建一个单例的数据库连接对象,提供方法来执行数据库查询和更新操作,并在应用启动时建立连接,在应用关闭时关闭连接。

    常见的场景就是:web 实时通信 SSE连接

 

如何实现单例模式?

 单例模式实现有多种方式,如下:

一、全局对象(不推荐)

  两种实现方式:

  1. 在全局环境中用 var 字面量声明一个对象,利用 var 的变量提升 + 全局属性的特点(全局环境下的 var 变量会自动成为全局属性),所以慎用 var
  2. 直接挂载到 全局对象 window 上

  优点:

    使用简单

  缺点:

    会存在全局污染

 

  实例如下:

// 例1:
window.jQuery = window.$ = jQuery;

// 例2:
window._ = lodash

// 例3:
// 全局环境下的 var 变量会自动成为全局属性
var singleUser = {
    name: 'sam',
    id: 1001
}
//使用
console.log(singleUser.name) // sam
console.log(window.singleUser.name) // sam

 

二、立即执行函数  +  闭包实现

思路:利用 JS 的闭包 来保存那个唯一对象实例,这样就可以 通过 new 来获取唯一实例对象。

 

实例如下:

const GlobalUser = (function () {
    let instance  // 闭包保存的唯一实例对象

    function createInstance(obj){
        return obj
    }

    return function(obj) {
        if(!instance){
            instance = createInstance(obj)
        }
        
        return instance
    }
})()  // 立即执行,外层函数的价值就是他的闭包变量 instance

console.log(new GlobalUser({name: 'sam', id: '1001'}).name) // sam

// 依然是 sam,复用了第一次创建的实例
console.log(new GlobalUser({name: 'baby', id: '1002'}).name) // sam

console.log(new GlobalUser() === new GlobalUser()) // true

 

三、ES6 实现

  1、ES6 类

class Singleton {
    constructor(){
        if(!Singleton.instance){
            Singleton.instance = this
        }
        return Singleton.instance;
    }
}

 

  2、ES6 模块 Module 

  ES6 的模块其实就是单例模式,模块中导出的对象就是单例的,多次导入其实是同一个引用。

  • Singleton 模式:import 模块的代码只会执行一次,同一个 url 文件只会第一次导入时执行代码。后续任何地方 import 都不会执行模块代码了,也就是说,import 语句是 Singleton 模式的。
  • 只读 - 共享:模块导入的接口的是只读的,不能修改。当然引用对象的属性值是可以修改的,不建议这么干,注意模块是共享的,导出的是一个引用,修改后其他方也会生效。

因此用 ESM 实现单例就比较简单了。

// 模块声明 config.js
export default {
    title: '设计模式'
}
// 使用
import config from './config.js'
console.log(config)  // {title: '设计模式'}
config.title = '修改一下'

import config2 from './config.js'
console.log(config, config2)  // {title: '修改一下'}  {title: '修改一下'}

 

 

单例模式的注意事项

  1、线程安全

    在多线程环境下,需要确保单例的创建是线程安全的。可以使用锁或其他同步机制来保证在多个线程同时访问单例时,只有一个实例被创建

  2、延迟加载

    可以考虑使用延迟加载的方式来创建单例实例,即在第一次访问单例时才创建实例。这样可以避免在应用启动时就创建一些可能不需要的对象,提高应用的启动速度。

  3、可扩展性

    在设计单例类时,要考虑到未来可能的扩展需求。尽量保持单例类的接口简洁和可扩展,以便在需要时可以方便地添加新的功能。

 

标签:对象,模式,instance,实例,单例,全局,设计模式,前端开发
From: https://www.cnblogs.com/bala/p/18514020

相关文章

  • 设计模式 - 简单工厂模式
    目录一、基本概念二、组成部分三、举例说明3.1 定义产品接口 3.2 定义具体产品类3.3 定义工厂类3.4 客户端代码四、优缺点4.1优点4.2缺点五、总结5.1适用场景5.2不适用场景5.3替代模式简单工厂模式(SimpleFactoryPattern)虽然不是GoF设计模式的一......
  • 前端开发 npm ,pnpm
    npmpnpm通过npm安装pnpm安装npminstall-gpnpm安装指定版本[email protected]或者npminstall-gpnpm@X查看当前pnpm版本pnpm-v或pnpm-version卸载npmrm-gpnpm升级版本pnpmadd-gpnpmtoupdate常用命令对比npm命令pnpm......
  • 06.动态代理设计模式
    06.动态代理设计模式目录介绍01.为何要动态代理1.1为何要动态代理1.2动态代理思考02.动态代理的概念2.1动态代理定义2.2动态代理类比理解2.3动态代理参与者2.4动态代理步骤03.动态代理的实现3.1罗列一个场景3.2用一个例子理解代理3.3基于接口动态代......
  • 前端开发者必学:mo.js动画库
    前端开发者必学:mo.js动画库前言在当今的网页设计中,动态效果和交互性是提升用户体验的关键因素。mo.js,一个轻量级的JavaScript动画库,为前端开发者提供了一种简单而强大的方法来创建引人注目的动画效果。本文将向您介绍mo.js的基本概念、特点、使用场景以及如何在Vue环境......
  • Java设计模式-单例模式和工厂模式的思路解析
    前言什么是设计模式?是广大程序员们总结汇总的一些编码套路,通常被用于底层内容的编写单例模式一个类只能被实例化一个对象饿汉式忽略需求,直接创建唯一实例/***单例模式-饿汉式*/publicclassClassA{//用来返回的唯一实例//static:1.保证getClassA......
  • 实验7:单例模式(学号的单一 )
    [实验任务一]:学号的单一仿照课堂的身份证的例子,实现每个同学仅有一个学号这一问题。1. 类图 1. 源代码//StudentID.javapackagetest7; publicclassStudentID{    privatestaticStudentIDinstance=null;    privateStringid;     privat......
  • 策略设计模式
    设计模式-策略设计模式策略设计模式(StrategyPattern)是一种行为设计模式,它定义了一系列算法,并将每个算法封装起来,使它们可以互相替换。这种模式让算法独立于使用它的客户端。简而言之,策略模式允许在运行时更改算法的行为。策略模式的组成部分:Context(上下文):上下文指的是......
  • C#05-设计模式学习笔记
    @目录1.设计模式的七大原则1.单一职责原则2.迪米特法则3.里氏代换原则4.依赖倒置原则5.接口隔离原则6.开闭原则7.合成复用原则8.总结2.创建型模式1.单例模式2.工厂方法模式1.简单工厂模式2.工厂模式3.抽象工厂模式4.生成器模式5.原型模式3.结构型设计模式1.适配器模式行为型设计模......
  • 前端开发设计模式——观察者模式
    目录一、定义和特点1.定义2.特点二、实现方式1.使用JavaScript实现观察者模式的基本结构2.实际应用中的实现示例三、使用场景1.事件处理2.数据绑定3.异步通信4.组件通信四、优点1.解耦和灵活性2.实时响应和数据一致性3.提高代码的可复用性五、缺......
  • java设计模式,英雄联盟的例子学习结构型模式
    结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。结构型模式主要关注类或对象的组合,帮助确保如果一个系统的结构发生变化,系统的其他部分不会受到影响。适配器模式主要组成部分目标接口(Target):客户端所期待的接口。源类(Adapt......