美文网首页让前端飞TypeScript 极简教程
实现一个ts单例模式基类(支持代码提示、禁止二次实例化)

实现一个ts单例模式基类(支持代码提示、禁止二次实例化)

作者: 来一斤BUG | 来源:发表于2023-10-15 16:19 被阅读0次

先贴出我的代码,后面再讲讲为什么要这么做:

class Singleton {
    // 实例
    private static _instance: Singleton;
    // 是否是通过getInstance实例化
    private static _instantiateByGetInstance: boolean = false;
    
    /**
     * 获取实例
     */
    public static getInstance<T extends Singleton>(this: (new () => T) | typeof Singleton): T {
        const _class = this as typeof Singleton;
        if (!_class._instance) {
            _class._instantiateByGetInstance = true;
            _class._instance = new _class();
            _class._instantiateByGetInstance = false;
        }
        return _class._instance as T;
    }
    
    /**
     * 构造函数
     * @protected
     */
    protected constructor() {
        if (!(this.constructor as typeof Singleton)._instantiateByGetInstance) {
            throw new Error("Singleton class can't be instantiated more than once.");
        }
    }
}

我在网上搜索了一遍,大多数文章里的ts单例模式或多或少是不够完美的,我的单例模式有以下几个优点:

  1. 子类可以直接继承此Singleton类,无需其他多余代码,比如
class TestClass extends Singleton {
    
}
  1. 支持IDE代码提示
class TestClass extends Singleton {
    testFunc() {
        
    }
}
代码提示
  1. 禁止使用new关键字实例化


    禁止实例化

接下来讲讲为什么要这么写

  • getInstance有泛型参数T,它需要继承Singleton,使用的时候不需要添加泛型参数,当然加上也没问题,比如:TestClass.getInstance<TestClass>()
  • ts函数参数列表中的第一项可以为this。这个this只是用于手动告诉ts编译器它的类型,实际并不需要传入。
  • this参数的类型为(new () => T) | typeof Singleton联合类型。new () => T表示某个构造函数类型,由于TestClass继承自Singleton,同时getInstance是静态方法,所以这里的new () => T代表的是TestClass类。使用了new () => T,就能告诉编辑器当前使用了哪个类,但是这样一来构造函数使用protected或者private修饰时会在编译阶段报错,可能会提示Cannot assign a 'protected' constructor type to a 'public' constructor type.,意思是无法将“protected”构造函数类型分配给“public”构造函数类型。这时候我们可以指定this的类型为(new () => T) | typeof Singleton联合类型。typeof Singleton表示Singleton类的类型,因为在类的内部可以实例化受保护的或者私有的构造函数,从而规避掉上述错误。
  • 将构造函数用protected修饰依然无法避免某些大聪明在子类内部实例化,所以构造函数内部使用了_instantiateByGetInstance判断是否是通过getInstance方法进行实例化的。当然这个问题只能在运行期间被发现。
class TestClass extends Singleton {
    testFunc() {
        new TestClass();
    }
}
抛出错误

相关文章

  • 设计模式:单例

    单例模式的基本介绍单例模式的实现源码中的单例模式记录 单例模式的基本介绍 定义:确保一个类只有一个实例,自行实例化...

  • python高级中的单例、异常、模块

    一、单例模式 单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,单例模式...

  • 单例模式

    什么是单例模式? 一个类只允许创建一个实例,那个类就是单例类。这个模式就是单例模式。单例模式实现方式:饿汉式:实现...

  • 单例模式

    单例模式 当系统中对于某个类,只需要有一个实例化对象时,可以使用单例模式。 单例模式实现方式 单例模式的实现主要有...

  • 常见的设计模式

    单例模式 核心思想:禁止外部实例化,统一有类内部实例化对象有且只有一个实例返回给外部调用。实现思路:1.私有化cl...

  • Thread-safe singleton

    单例模式的概念 单例模式就是确保只有一个实例,而且自行实例化并向整个系统传递这个实例,这个类就称作为单例类 单例模...

  • java与kotlin实现单例模式

    单例模式的意义: 确保一个类只有一个实例,而且自行实例化并且向系统提供这个实例。 单例模式的实现条件 ①一个pri...

  • Python中的单例、异常、模块

    一、单例模式 什么是单例模式?确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,...

  • 设计模式之单例模式

    单例模式 单例模式定义 确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供...

  • ios 单例 Singleton

    单例模式就是只有一个实例,确保一个类只有一个实例,并且自行实例化并向整个系统提供这个实例,一个单例类可以实现在不同...

网友评论

    本文标题:实现一个ts单例模式基类(支持代码提示、禁止二次实例化)

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