美文网首页
3、单例模式

3、单例模式

作者: 懂会悟 | 来源:发表于2023-04-24 08:22 被阅读0次

一、概念

保证一个类仅有一个实例,并提供一个访问它的全局访问点,这样的模式就叫做单例模式。

单例模式是设计模式中相对较为容易理解、容易上手的一种模式,同时因为其具有广泛的应用场景,也是面试题里的常客。

二、实现思路

现在我们先不考虑单例模式的应用场景,单看它的实现,思考这样一个问题:如何才能保证一个类仅有一个实例? 一般情况下,当我们创建了一个类(本质是构造函数)后,可以通过new关键字调用构造函数进而生成任意多的实例对象。像这样:

class SingleDog {
  show() {
    console.log("我是一个单例对象");
  }
}

const s1 = new SingleDog();
const s2 = new SingleDog();

// false
s1 === s2

我们先 new 了一个 s1,又 new 了一个 s2,很明显 s1 和 s2 之间没有任何瓜葛,两者是相互独立的对象,各占一块内存空间。而单例模式想要做到的是,不管我们尝试去创建多少次,它都只给你返回第一次所创建的那唯一的一个实例。
要做到这一点,就需要构造函数具备判断自己是否已经创建过一个实例的能力。我们现在把这段判断逻辑写成一个静态方法(其实也可以直接写入构造函数的函数体里):

三、简单demo

class SingleDog {
  show() {
    console.log("我是一个单例对象");
  }
  static getInstance() {
    // 判断是否已经new过1个实例
    if (!SingleDog.instance) {
      // 若这个唯一的实例不存在,那么先创建它
      SingleDog.instance = new SingleDog();
    }
    // 如果这个唯一的实例已经存在,则直接返回
    return SingleDog.instance;
  }
}

const s1 = SingleDog.getInstance()
const s2 = SingleDog.getInstance()

除了以上这种实现方法,也可以利用闭包来实现:

class SingleDog {
  show() {
    console.log("我是一个单例对象")
  }
}

SingleDog.getInstance = (function () {
  // 定义自由变量instance,模拟私有变量
  let instance = null
  return function () {
    // 判断自由变量是否为null
    if (!instance) {
      // 如果为null则new出唯一实例
      instance = new SingleDog();
    }
    return instance;
  }
})()

const res = SingleDog.getInstance()
console.log(res.show())

四、扩展

1.Vuex中的单例模式

Vuex 使用单一状态树,用一个对象就包含了全部的应用层级状态。至此它便作为一个“唯一数据源 (SSOT)”而存在。这也意味着,每个应用将仅仅包含一个 store 实例。单一状态树让我们能够直接地定位任一特定的状态片段,在调试的过程中也能轻易地取得整个当前应用状态的快照。 ——Vuex官方文档

在Vue中,组件之间是独立的,组件间通信最常用的办法是 props(限于父组件和子组件之间的通信),稍微复杂一点的(比如兄弟组件间的通信)我们通过自己实现简单的事件监听函数也能解决掉。

但当组件非常多、组件间关系复杂、且嵌套层级很深的时候,这种原始的通信方式会使我们的逻辑变得复杂难以维护。这时最好的做法是将共享的数据抽出来、放在全局,供组件们按照一定的的规则去存取数据,保证状态以一种可预测的方式发生变化。于是便有了 Vuex,这个用来存放共享数据的唯一数据源,就是 Store。

Vuex如何确保Store的唯一性

我们先来看看如何在项目中引入 Vuex:

// 安装vuex插件
Vue.use(Vuex);

// 将store注入到Vue实例中
new Vue({
  el: "#app",
  store,
})

通过调用Vue.use()方法,我们安装了 Vuex 插件。Vuex 插件是一个对象,它在内部实现了一个 install 方法,这个方法会在插件安装时被调用,从而把 Store 注入到Vue实例里去。也就是说每 install 一次,都会尝试给 Vue 实例注入一个 Store

在 install 方法里,有一段逻辑和我们楼上的 getInstance 非常相似的逻辑:

let Vue // 这个Vue的作用和楼上的instance作用一样
...

export function install (_Vue) {
  // 判断传入的Vue实例对象是否已经被install过Vuex插件(是否有了唯一的state)
  if (Vue && _Vue === Vue) {
    if (process.env.NODE_ENV !== 'production') {
      console.error(
        '[vuex] already installed. Vue.use(Vuex) should be called only once.'
      )
    }
    return
  }
  // 若没有,则为这个Vue实例对象install一个唯一的Vuex
  Vue = _Vue
  // 将Vuex的初始化逻辑写进Vue的钩子函数里
  applyMixin(Vue)
}

以上便是 Vuex 源码中单例模式的实现办法了,套路可以说和我们的getInstance如出一辙。通过这种方式,可以保证一个 Vue 实例(即一个 Vue 应用)只会被 install 一次 Vuex 插件,所以每个 Vue 实例只会拥有一个全局的 Store。

相关文章

  • 单例模式

    目录 1、设计模式简介 2、什么是单例模式 3、单例模式应用场合 4、单例模式作用 5、单例模式3个要点/要素 6...

  • 单例模式和GCD单例实现

    1、传统单例模式2、GCD单例模式3、用宏实现GCD单例模式4、用宏实现GCD单例模式,名称随类名变化而变化 单例...

  • 设计模式之一:单例模式

    摘要:设计模式之一:单例模式目录介绍1.单例模式介绍2.单例模式定义3.单例模式使用场景4.单例模式的实现方式 4...

  • 单例模式

    2020.01.10 晚 22:01 问题 我们从下面3个问题去对单例模式进行探讨 为什么需要单例模式? 单例模式...

  • 设计模式第二篇、单例设计模式

    目录1、什么是单例设计模式2、单例设计模式的简单实现3、单例设计模式面临的两个问题及其完整实现4、单例设计模式的应...

  • 单例模式

    3、单例模式(Singleton) 单例对象(Singleton)是一种常用的设计模式。在Java应用中,单例对象...

  • 设计模式之单例模式

    文章结构1.单例模式简介2.单例模式种类3.参考文章 1.单例模式简介 1.1简介 单例模式,从字面上看是“一个实...

  • 单例模式

    单例模式的特点:1.单例模式只有一个实例。2.单例模式自己创建自己的对象实例。3.单例模式必须给所有其他对象提供这...

  • kotlin实现单例模式

    1.懒汉式实现单例模式 2.线程安全懒汉式实现单例模式 3.双重校验懒汉式实现单例模式 4.静态内部类方式实现单例模式

  • 【设计模式】单例模式

    单例模式 常用单例模式: 懒汉单例模式: 静态内部类单例模式: Android Application 中使用单例模式:

网友评论

      本文标题:3、单例模式

      本文链接:https://www.haomeiwen.com/subject/ehaeddtx.html