序章

シングルトンは、最もよく知られているデザインパターンの1つです。 クラスのインスタンスが1つだけで、それ以下である必要がある場合があります。 この1つのクラスは、ある種のリソースマネージャーまたは値のグローバルルックアップである可能性があります。 これがシングルトンの出番です。

この記事では、シングルトンとは何か、そしてそれらをJavaScriptで最適に実装する方法を見ていきます。

前提条件

このチュートリアルを正常に完了するには、次のものが必要です。

  • JavaScriptでのコーディングの理解。 この分野でさらに知識を広げる必要がある場合は、このJavaScriptシリーズをチェックしてください。
  • JavaScriptでクラスがどのように機能するかについての理解。 このJavaScriptでのクラスの理解チュートリアルはこれを提供できます。

シングルトンを理解する

シングルトンは、クラスが存在しない場合、または既存のクラスの参照を返す場合に、クラスのインスタンスを作成するために使用されます。 これは、グローバルスコープでのアプリケーションの実行中にシングルトンが1回だけ作成されることを意味します。

この定義に基づくと、シングルトンはグローバル変数に非常に似ているように見えます。 グローバル変数を使用するコーディング言語でシングルトンを使用する必要があるのはなぜか疑問に思われるかもしれません。 シングルトンをグローバル変数とは異なるものにするいくつかのことがあります。

  • グローバル変数は字句スコープですが、シングルトンはスコープされていません。 これは、プログラミングブロック内にグローバル変数と同じ名前の別の変数がある場合、最初の参照が優先されることを意味します。 ただし、シングルトンでは、その参照を再宣言しないでください。
  • シングルトンの値は、メソッドを介して変更されます。
  • シングルトンは、プログラムが終了するまで解放されません。これは、グローバル変数の場合には当てはまらない可能性があります。

グローバル変数をサポートする言語でも、シングルトンは非常に便利です。 シングルトンが便利なシナリオがあります。 シングルトンの一部のアプリケーションは、ロガーオブジェクトまたは構成設定クラスです。

シングルトンの宣言

シングルトンを宣言する方法はいくつかあります。 これはあなたが見るかもしれない1つのフォーマットです:

var SingletonInstance = {
 method1: function () { ... }
 method2: function () { ... }
};

このシングルトンは、次のようにコンソールに記録されます。

console.log(SingletonInstance.method1());
console.log(SingletonInstance.method2());

これはシングルトンを宣言するための最良の方法ではないことを覚えておくのは良いことです。 もう1つの方法は、シングルトンを1回作成するファクトリクラスを使用することです。

var SingletonFactory = (function(){
  function SingletonClass() {
    // ...
  }

  var instance;

  return {
    getInstance: function(){
      if (!instance) {
        instance = new SingletonClass();
        delete instance.constructor;
      }
      return instance;
    }
  };
})();

クラス定義はプライベートであり、コンストラクターは最初のインスタンスの作成後に削除されるため、これは最初の例のより良い代替手段です。 これにより、プログラムで重複するシングルトンが作成されるのを防ぐことができます。 このアプローチの欠点は、ファクトリパターンに非常に似ていることです。

まだ3番目のアプローチがあります。 このアプローチは、ES6クラスとObject.freeze()メソッドの組み合わせを実装します。

script.js
class Singleton {
  constructor() {
   // ...
  }

  method1() {
    // ...
  }

  method2() {
    // ...
  }
}

const singletonInstance = new Singleton();

Object.freeze(singletonInstance);

Object.freeze()メソッドは、オブジェクトのプロパティと値の変更を防ぎます。 したがって、Object.freeze()singletonInstanceに適用すると、コードの後半でそのプロパティや値を変更できなくなります。

さらに進んで、このシングルトンをモジュールとして記述し、ES6エクスポート機能を使用してエクスポートできます。

script.js
export default singletonInstance;

次に、このシングルトンをインポートすることで、別のファイルで使用できます。

otherFile.js
import mySingleton from './script.js';

mySingleton.method1();

シングルトンを作成するためのこれらの3つのアプローチを使用して、高い可読性を可能にする特定のユースケースに最適な方法を選択します。

結論

JavaScriptコードでシングルトンを使用する必要は必ずしもありません。 アプリケーションの状態に影響を与えない場合は、シングルトンを使用してください。 この制約により、大きなアプリケーションでの使用が大幅に制限されます。

ツールキットにこの基本的なデザインパターンが含まれているので、JavaScriptファクトリパターンを調べたいと思うかもしれません。 状態管理について詳しく知りたい場合は、React withRedux状態管理とReactフックを使用した状態管理に関するこれらの記事を確認してください。