在NodeJS中导出NON-singleton类的正确方法是什么?

时间:2017-03-04 21:26:48

标签: javascript node.js ecmascript-6

我最近了解到,在大多数情况下,所有节点模块都被缓存并且与单例类似。

我想解决的问题是没有返回同一个实例中的每个导入结果。这可能很容易弄清楚,但是我很难登陆坚固的设计模式,因为我是Node和ES6的新手。

我努力实现的目标是:

  • 私人字段
  • 导入模块的消费者可以新建实例
  • 比较实例

我能想出的最好成绩如下:

export default () => {
   let _foo = 'bar';

   return new class {
      get foo() {
         return _foo;
      }

      set foo(value) {
         _foo = value;
      }
   };
};

然而,这并不能完全达到我想要实现的所有目标。

使用此方法导入模块无法使用instanceof来比较原型。

如果导入者在创建实例时使用new关键字也无关紧要。调用let instance = new Module()let instance = Module()会导致同样的事情。

我试图通过从函数返回中删除new关键字来解决这个问题,但是这导致导入程序必须执行以下操作来获取新实例:new (Module())

我也尝试过导出构造函数,但这导致了私有字段的丢失。

从节点模块导出构造函数/类的正确方法是什么?

更新:

在玩了一些之后,我能够想出以下内容:

const _sFoo = Symbol();

export default class {
   constructor() {
      this[_sFoo] = 'default';
   }

   get foo() {
      return this[_sFoo];
   }

   set foo(value) {
      this[_sFoo] = value;
   }
}

这似乎符合我的所有目标,但我仍然不确定这是否是最好的设计模式...

1 个答案:

答案 0 :(得分:3)

  

我想解决的问题是没有返回同一个实例中的每个导入结果。这可能很容易弄清楚,但是由于我是Node和ES6的新手,因此无法登陆稳固的设计模式。

您有几个选择:

  1. 您可以导出构造函数,让正在加载模块的代码调用该构造函数来创建自己的对象。这允许调用代码根据需要创建任意数量的独立对象。导出构造函数需要调用者使用new,除非构造函数明确检测到它们在没有new的情况下被调用,然后再适应仍然返回一个新实例。

  2. 您可以导出工厂函数,让正在加载模块的代码调用该工厂函数,以根据需要创建任意数量的对象。工厂函数将被称为普通函数,并且每次调用它时都会返回一个新对象。

  3. 您可以导出一个方法,该方法在调用时可以执行任何操作,包括创建所需对象并返回它(也可能嵌入其他对象中)。这只是工厂功能的一种变体,但可能同时包含很多东西。

  4.   

    我想要实现的目标是:

         

    私人字段

    以上对每个对象的私有字段都没有帮助。这是一个完全独立的讨论。

      

    导入模块的消费者可以新建实例

    上面的选项1允许呼叫者直接使用new。其他选项是工厂功能,因此他们不会使用new

      

    比较实例

    您必须直接导出构造函数(上面的选项1)才能使用instanceof。其他选项不会导出构造函数,因此您没有任何内容可以使用instanceof

      

    从节点模块导出构造函数/类的正确方法是什么?

    您只需导出构造函数。在Javascript中,构造函数只是函数,因此您只需导出构造函数,然后调用者就可以使用let x = new SomeConstructor()创建自己的对象。他们同样可以使用if (x instanceof SomeConstructor)。使用ES6语法,您只需导出类名称,这相当于导出构造函数。