在 TypeScript 中扩展单例类

Kha*_*med 5 design-patterns typescript

我正在尝试扩展和重写 TypeScript 中单例类中的方法,这是单例类的代码

class Singleton {
    protected static _instance: Singleton;

    protected constructor() { }

    public static get instance() {
        if (Singleton._instance === undefined) {
            Singleton._instance = new Singleton();
        }

        return Singleton._instance;
    }

    public doWork() {
        console.log('doing work in singleton...');
    }
}
Run Code Online (Sandbox Code Playgroud)

扩展单例类:

class ExtendedSingleton extends Singleton {
    protected static _instance: ExtendedSingleton;

    protected constructor() {
        super();
    }

    public static get instance() {
        console.log('Creating Extended Singleton');
        if (ExtendedSingleton._instance === undefined) {
            ExtendedSingleton._instance = new ExtendedSingleton();
        }

        return ExtendedSingleton._instance;
    }

    public doWork() {
        console.log('doing work in extended singleton...');
    }
}
Run Code Online (Sandbox Code Playgroud)

最后是运行这两个类的代码:

Singleton.instance.doWork();
ExtendedSingleton.instance.doWork();
Run Code Online (Sandbox Code Playgroud)

问题是两个日志都记录'doing work in singleton...',当我交换线路时,问题就解决了。我不知道为什么会发生这种行为(我认为这主要是我不知道javascript的继承是如何工作的),或者是否有更好的解决方案来解决我的问题。

注意:我通过使用接口并在两个类中实现它来解决这个问题,但这在我只需要重写一两个方法的大型类中效率不高。

Nic*_*las 4

由于Singletonwill 是 的原型ExtendedSingleton,因此每当您访问 上的任何静态属性时ExtendedSingleton,它都会Singleton首先检查该属性。

这意味着如果首先_instance设置Singleton,则将ExtendedSingleton._instance返回该值。它以另一种顺序工作,因为如果ExtendedSingleton没有_instance字段,它会先获得自己的字段,然后再Singleton获得字段。

如果您将其设置_instance为私有而不是受保护(因为每个类无论如何都应该有自己的),Typescript 会注意到这个问题并给您一个错误。

解决此问题的一种方法是重命名_instance一个或两个类,以确保它们都有自己的字段。

  • 更改名称可以解决该问题,同时还强制在 ExtendedSingleton _instance 中使用一个值来修复该问题(使用 undefined 或 null 对其进行初始化)。如果有其他解决方案请告诉我,谢谢。 (2认同)