Node.jsでシングルトンなクラスモジュール

Node.jsでシングルトンなクラスモジュールの作り方のメモです。Node.jsでシングルトンなモジュールの作り方は他にも色々ありますが、クラスでなおかつシンプルなやり方となると今回のやり方が一番シンプルではないかと思います。

では、クラスモジュールのシングルトン化を説明する前に、まずはおさらいで普通の(非シングルトンな)クラスモジュールの例から見ていきましょう。以下のような単純なクラスモジュールがあったとします。

// Foo.js

class Foo {
  constructor() {
      //
  }

  hello() {
    console.log("hello!");
  }
}

// export!
module.exports = Foo;

このクラスを使うときは大体このようにすると思います:

const Foo = require("./Foo.js");
const foo = new Foo();
foo.hello(); // "hello!"

説明するまでなく、Fooクラスをnewする度に新しいインスタンスが生成されます。

それでは、これをシングルトン化してみましょう。

シングルトン化

先ほどのFooクラスモジュールをシングルトン化すると以下のようになります:

シングルトンなクラス

// Foo.js

class Foo {
  constructor() {
      //
  }

  hello() {
    console.log("hello!");
  }
}

// export as singleton:
module.exports = new Foo();

上記のコードでやっていることは、Fooクラス自身ではなくFooインスタンスmodule.exports にセットしているだけです。たったこれだけで、Fooクラスの中身自体を弄ることなくシングルトン化できます。

このシングルトンクラスを使う時はこのようにします:

const Foo = require("./Foo.js");
Foo.hello(); // "hello!"

おまけ: ブラウザ対応のクラスモジュール

せっかくなのでブラウザ対応のクラスモジュールのシングルトン化もメモしておきます。

たとえば以下のようなブラウザ対応クラスモジュールがあるとします。

ブラウザ対応クラスモジュール

// Foo.js

class Foo {
  constructor() {
      //
  }

  hello() {
    console.log("hello!");
  }
}

// export with browser support!
if (typeof module !== "undefined" && typeof module.exports !== "undefined") {
  module.exports = Foo;
} else {
  window.Foo = Foo;
}

これをシングルトン化すると以下のようになります。やっていることは先ほどまでのシングルトン化の手法と同じです:

シングルトンなブラウザ対応クラスモジュール

// Foo.js

class Foo {
  constructor() {
      //
  }

  hello() {
    console.log("hello!");
  }
}

// export as singleton with browser support!
if (typeof module !== "undefined" && typeof module.exports !== "undefined") {
  module.exports = new Foo();
} else {
  window.Foo = new Foo();
}

以上です。

PR:時事ネタチェックの時間節約!
芽萌丸プログラミング部 @programming
プログラミング関連アカウント。Web標準技術を中心に書いていきます。フロントエンドからサーバサイドまで JavaScript だけで済ませたい人たちの集いです。