TypeScriptでのSingletonパターン - 完全ガイドと実装例

TypeScript実装例でSingletonデザインパターンを学びましょう。データベース接続、設定マネージャー、ロギングサービスでSingletonを使うべき場面を理解します。

Creational

詳細な説明

Singletonパターン

Singletonパターンは、クラスがただ1つのインスタンスしか持たないことを保証し、そのインスタンスへのグローバルなアクセスポイントを提供します。ソフトウェアエンジニアリングにおいて最もシンプルでありながら最も議論されるデザインパターンの一つです。

動作の仕組み

Singletonパターンは、コンストラクタをprivate(またはprotected)にし、最初の呼び出し時にインスタンスを作成し、以降の呼び出しでは同じインスタンスを返す静的メソッドを提供することで動作します。

class AppConfig {
  private static instance: AppConfig | null = null;
  private settings: Map<string, string> = new Map();

  private constructor() {}

  static getInstance(): AppConfig {
    if (!AppConfig.instance) {
      AppConfig.instance = new AppConfig();
    }
    return AppConfig.instance;
  }

  set(key: string, value: string) {
    this.settings.set(key, value);
  }

  get(key: string): string | undefined {
    return this.settings.get(key);
  }
}

主な特徴

  • 遅延初期化: インスタンスは最初にリクエストされた時のみ作成され、起動時のリソースを節約します。
  • グローバルアクセス: アプリケーションのどの部分からでも静的メソッドを通じて同じインスタンスにアクセスできます。
  • スレッドセーフティ: 並行環境では、複数のインスタンスを防ぐためにロックやダブルチェックロッキングなどの追加的な配慮が必要です。

よくある落とし穴

Singletonはグローバル状態を導入するため、テストが同じインスタンスを共有してしまい、ユニットテストが困難になります。現代のフレームワークでは、依存性注入コンテナがオブジェクトのライフサイクルを一元管理することで、Singletonパターンを置き換えることが多くあります。Singletonを使おうとしている場合は、依存性注入がより適切かどうかを検討してください。

使用を避けるべき場面

将来複数のインスタンスが必要になる可能性がある場合、コードのテストが困難になる場合、またはクラス間の依存関係を隠してしまう場合はSingletonの使用を避けましょう。

ユースケース

Singletonは、アプリケーション全体で共有状態を管理する単一のインスタンスのみが必要なデータベース接続プール、アプリケーション設定マネージャー、ロギングサービス、キャッシュレイヤーに一般的に使用されます。

試してみる — Design Pattern Reference

フルツールを開く