辛格尔顿的目标



创建Singleton对象的最佳方法是什么?我有一个类,它将在不同的应用程序之间共享。这个类应该是一个单独的PER应用程序。

这是我目前拥有的。然而,当我实例化app1两次时,它会为此创建一个新实例。

class Sample {
constructor(appName) { // eslint-disable-line
if (!Sample._instance[appName]) {
Sample._instance[appName] = this
console.log('Creating new instance')
this.counter = 0
}
return Sample._instance[appName]
}
getVal () {
this.counter++
console.log('counter: ' + this.counter)
}
}

然后我这样称呼它:

import Sample from './sample'

const sample1 = new Sample('app1')
sample1.getVal() // OK - prints 1
sample1.getVal() // OK - prints 2
const sample1a = new Sample('app1')
sample1a.getVal() // NOK - prints 1 - should print 3
const sample2 = new Sample('app2')
sample2.getVal() // OK - prints 1
sample2.getVal() // OK - prints 2

如果我做了下面这样的事情,那么当实例已经在import期间创建时,我怎么能真正传入appName呢?

const sample = new Sample(appName)
export default sample

仅添加static _instance = {}就消除了我遇到的运行时错误,并使其按您的意愿工作。

我还在nodejs中测试了这一点,以确保在导入类而不是在同一文件中声明类时不会发生任何奇怪的事情。

class Sample {
static _instance = {};
constructor(appName) { // eslint-disable-line
if (!Sample._instance[appName]) {
Sample._instance[appName] = this
console.log('Creating new instance')
this.counter = 0
}
return Sample._instance[appName]
}
getVal () {
this.counter++
console.log('counter: ' + this.counter)
}
}
const sample1 = new Sample('app1')
sample1.getVal() // OK - prints 1
sample1.getVal() // OK - prints 2
const sample1a = new Sample('app1')
sample1a.getVal() // NOK - prints 1 - should print 3
const sample2 = new Sample('app2')
sample2.getVal() // OK - prints 1
sample2.getVal() // OK - prints 2

区分容器对象和单例对象的角色。

下面我制作了一个IIFE单例container,它处理创建和存储Sample的新实例,如果已经存储了,它将返回一个现有实例。

您可以将类定义和容器singleton保存在它们自己的文件中,并导出容器。由于它已经在模块中被调用,您只需要在导入脚本中调用container.get('app')

class Sample {
constructor() {
console.log('Creating new instance')
this.counter = 0
}
getVal () {
this.counter++
console.log('counter: ' + this.counter)
}
}
const container = (() => {
const singletons = {};

const get = (appName) =>{
if (!singletons[appName]){
singletons[appName] = new Sample();
}
return singletons[appName]
}
return { get }
})();
let sample1 = container.get('app1')
sample1.getVal();
sample1.getVal();
let sample1A = container.get('app1')
sample1A.getVal();
let sample3 = container.get('app2')
sample3.getVal();

相关内容

最新更新