javascript创建或设计Singleton类的好方法

时间:2018-10-27 15:15:35

标签: javascript node.js design-patterns

我认为在javascript中它可以创建如下的Singleton类

test.js
class Container {
    constructor() {
      this.map = new Map;
    }

    set(key, value) {
      this.map.set(key, value);
    }

    get(key) {
      return this.map.get(key);
    }
  }
module.exports.Container = new Container();

这样 我可以在index.js中使用其他文件

import container from './test'

但是,Container的构造函数需要一些其他参数,以便可以做得更好。并且Container也需要为Singleton类, 因为这是一个普通的阶级。而且我不知道如何创建它?

constructor(servie) {
      this.map = new Map;
      this.servie = servie;
    }

通过在应用程序启动时创建服务变量的方式

1 个答案:

答案 0 :(得分:0)

编辑:我已经意识到我的命名有些混乱,因为我使用Container来表示IoC容器,然后意识到您已经使用该名称来表示您的Singleton。

假设您能够在代码的中心点(例如,在设置服务器时进入点文件)实例化您的单例。您可以通过多种方式实现单例。例如:

let instance = null;
class Singleton {
  constructor(arg1, arg2) {
    this.arg1 = arg1;
    this.arg2 = arg2;
  }
}

module.exports = (...args) => {
  return instance || (instance = new Singleton(...args));
}

您可以通过多种方式执行此操作,例如使用静态函数而不是匿名函数。但是,考虑到所有这些,我认为对于您是在初始化实例还是在尝试检索实例,我感到有些困惑。

我认为,IoC容器模式(通常在C#项目中使用)更加简洁。您可能只有一个容器类,可以跟踪您的单例并提供单独的访问和初始化函数。

class Container {
  constructor() {
    this.instances = {};
  }

  add(name, instance) {
    this.instances[name] = instance; // depends if you want overwrite or not
  }

  get(name) {
    if (!this.instances[name]) {
      throw new Error('some appropriate error messaging for your app');
    }
    return this.instances[name];
  }

  remove(name) {
    delete this.instances[name];
  }
}

module.exports = new Container(); // this has to be a no-param constructor

然后在您的应用初始化代码中,初始化单例并在容器中注册它们:

const Container = require('<path_to_Container>');
const Singleton = require('<path_to_Singleton>');
...
Container.add('mySingleton', new Singleton(arg1, arg2));

,并随时通过以下方式访问它:

Container.get('mySingleton');

夫妇笔记:

  • 您可以使用Singleton.name代替字符串名称(示例中为“ mySingleton”)
  • 这只是个人喜好。但我喜欢它,因为它更具声明性,您可以在应用启动时将实例注册(添加)到容器中,并且不要模糊初始化和使用之间的界限。这意味着,如果以后添加更多这些单例,则已经有一个单一的模式。