【问题标题】:Is this a Singleton in Typescript?这是打字稿中的单身人士吗?
【发布时间】:2021-01-15 01:32:07
【问题描述】:

我了解到我们应该避免使用 Singleton。我想知道如果我以这种方式开发一个模块,我是在做一个单例吗?

class MyClass{

}

export default new MyClass();

因为每次我加载模块我都会得到相同的实例,不是吗?

谢谢

【问题讨论】:

  • 你的MyClass实际上是做什么的?如果它确实保持状态,是的,你应该避免只导出一个实例。如果它不保持状态,则不应使用class
  • 感谢您的链接。我只是想弄清楚为什么我在导入第三方模块时从未看到“新”。它们似乎都是单例,但如果应该避免它们如何构建它们?例如 Axios、Express、Lodash。您永远不会导入 lib,而不是“new Axios()”或“new Express()”。为什么?
  • Axios 没有全局状态 afaik,它只是导出一个函数。 express 实际上确实导出了一个“构造函数”,你可以在其中const app = new Express(),尽管这个构造函数也是一个单例实例,因为 express 通常用作具有一个全局实例的框架(和一个全局 http 服务器侦听到单个端口),他们希望简化这种用法。并不是说这是一个好习惯,但在某些用例中,这正是您所需要的。
  • 我正在研究 Axios 源代码,我认为 Axios 返回其类的实例。 github.com/axios/axios/blob/master/lib/axios.js 它导出了 createInstance() 函数的返回,该函数确实会返回一个新的 Axios 实例。所以和我正在做的没有什么不同。这还很糟糕吗?

标签: javascript typescript singleton es6-modules


【解决方案1】:

不是 Singleton ,往下看例子

class SingletonClass {

    private static _instance:SingletonClass = new SingletonClass();

    constructor() {
        if(SingletonClass._instance){
            throw new Error("Error: Instantiation failed: Use SingletonClass.getInstance() instead of new.");
        }
        SingletonClass._instance = this;
    }

    public static getInstance():SingletonClass
    {
        return SingletonClass._instance;
    }

}

https://codebelt.github.io/blog/typescript/typescript-singleton-pattern/

【讨论】:

  • 有很多单例模式。你的只是其中之一。您对“单例”的定义是什么?为什么您认为问题中的代码没有创建一个?
  • Singleton 应该一直是“一个实例”,在他的例子中我已经导入了两次,差异别名将是一个实例? @Bergi
  • 是的,无论您多久导入一个模块,您都会得到相同的导出值。别名根本不重要。
【解决方案2】:

让我们看一个单例的例子。

假设我有一个名为会计部门的班级,而在现实生活中,只有一个会计部门。因此,我们只需要一个实例。

class AccountingDepartment {

 private static accountingDepartment: AccountingDepartment;
 private id: number;
 private name: string;

 static getInstance(): AccountingDepartment {
    if (this.accountingDepartment) {
      return this.accountingDepartment;
    } else {
      this.accountingDepartment = new AccountingDepartment(2, 'AD');
      return this.accountingDepartment;
    }
  }

  private constructor(id: number, name: string) {
    this.id = id;
    this.name = name;
  }
}
const accounting = AccountingDepartment.getInstance();
const accounting1 = AccountingDepartment.getInstance();

如果您看到,accounting 和 accounting1 都会在控制台中为您提供相同的对象。所以只创建了一个单例实例。

这里需要注意的点:

  1. 这里使用了私有构造函数。这样没有其他类可以访问此构造函数
  2. 该方法是静态的,因为我们需要仅通过此处的类访问该方法
  3. getInstance 方法明确指出,如果已经存在该类的实例,则返回该实例,只有否则创建一个新实例并返回它。

由于只创建了一个类的单一实例,这就是它是单例模式的原因。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-30
    • 1970-01-01
    相关资源
    最近更新 更多