跳至主要內容

单例模式

微信公众号:储凡2023/11/29大约 7 分钟

单例模式

单例模式Singleton Pattern 又名单件模式或单态模式,属于创建型模式,其涉及到一个单一的类,该类负责创建所需的对象,同时确保只有单个对象被创建,这个类提供了一种访问其唯一的对象的方式,保证访问的对象是只实例化一次的对象类。

基本介绍

单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。单例模式主要有以下要点,首先是某个类只能有一个实例,再是其必须自行创建这个实例,以及其必须自行向整个系统提供这个实例。

模式结构

  • Singleton: 单例。
  • Proxy: 单例创建代理。

优点

  • 提供了对唯一实例的受控访问。因为单例类封装了它的唯一实例,所以它可以严格控制客户怎样以及何时访问它,并为设计及开发团队提供了共享的概念。
  • 由于在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象,单例模式无疑可以提高系统的性能。
  • 允许可变数目的实例。我们可以基于单例模式进行扩展,使用与单例控制相似的方法来获得指定个数的对象实例。

缺点

  • 由于单例模式中没有抽象层,因此单例类的扩展有很大的困难。
  • 单例类的职责过重,在一定程度上违背了单一职责原则。因为单例类既充当了工厂角色,提供了工厂方法,同时又充当了产品角色,包含一些业务方法,将产品的创建和产品的本身的功能融合到一起。

滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出;现在很多面向对象语言的运行环境都提供了自动垃圾回收的技术,因此如果实例化的对象长时间不被利用,系统会认为它是垃圾,会自动销毁并回收资源,下次利用时又将重新实例化,这将导致对象状态的丢失。

代码实现

Ts版本

/**
 * 单例模式
 * - 懒汉式
 * - 饿汉式
 */

/**
 * 懒汉-单例
 */
class LazySingleton {
  private static instance: LazySingleton
  private constructor() {
    // 私有化构造函数,防止通过 new 关键字创建实例
    console.log('防止通过 new 关键字创建实例')
  }

  public static getInstance() {
    if (LazySingleton.instance == null) {
      LazySingleton.instance = new LazySingleton()
    }
    return LazySingleton.instance
  }
}

// 使用示例
const lazyInstance1 = LazySingleton.getInstance()
const lazyInstance2 = LazySingleton.getInstance()

console.log(lazyInstance1 === lazyInstance2) // 输出: true

/**
 * 饿汉-单例
 */
class EagerSingleton {
  private static instance = new EagerSingleton()

  private constructor() {
    // 私有化构造函数,防止通过 new 关键字创建实例
    console.log('防止通过 new 关键字创建实例')
  }

  // 获取实例,静态方法
  public static getInstance(): EagerSingleton {
    return EagerSingleton.instance
  }
}

// 使用示例
const eagerInstance1 = EagerSingleton.getInstance()
const eagerInstance2 = EagerSingleton.getInstance()

console.log(eagerInstance1 === eagerInstance2) // 输出: true

Js版本

Java版本

更新日志

2024/7/28 18:06
查看所有更新日志
  • c0f2d-refactor: 升级vuepress相关版本,优化项目结构 (#137)
  • e6a79-feat: 大幅新增设计模式、Linux命令、ORM框架教程文档