ホームページ > ウェブフロントエンド > jsチュートリアル > シングルトン設計パターン: アプリケーションでのグローバル状態の管理

シングルトン設計パターン: アプリケーションでのグローバル状態の管理

Susan Sarandon
リリース: 2024-12-03 19:34:15
オリジナル
466 人が閲覧しました

アプリケーションの複数の部分で共有する必要があるオブジェクト (データベース接続、WebSocket クライアント、構成マネージャーなど) を扱っていることに気付いたことがありますか?

アプリケーションやプロセスのライフサイクル全体を通じて一貫性を保ち、アクセスできるようにするには、このようなオブジェクトをどのように管理すればよいでしょうか?ここで シングルトン デザイン パターン が登場します。

概要

シングルトン創造的なデザイン パターン であり、新しいオブジェクトを使用してオブジェクトを作成するネイティブな方法に伴うさまざまな問題に対処するデザイン パターンのカテゴリです。 キーワードまたは演算子。

シングルトン設計パターンは、次の 2 つの主要な問題を解決することに重点を置いています。

  1. インスタンスに グローバル アクセス ポイントを提供するにはどうすればよいですか?
  2. クラス または特定のタイプのオブジェクトのインスタンスが 1 つだけであることを確認するにはどうすればよいですか?

これにより、データベース接続、WebSocket クライアント、キャッシュ サービス、またはアプリケーションのライフサイクル全体を通じてメモリ内で永続化および変更する必要があるものなど、特定の種類またはタイプのグローバル状態を管理する方法が簡素化および標準化されます。

シングルトン設計パターンを実装するにはどうすればよいでしょうか?

Singleton Design Pattern: Managing Global States in Your Applications

上記のスキーマは次の TypeScript クラスに変換されます。

TypeScript の例

class Singleton {
  private static instance: Singleton
  // other properties...
  public authorName: string

  private constructor({ authorName }: { authorName: string }) {
    this.authorName = authorName
  }

  public static getInstance(params) {
    if (!this.instance) {
      this.instance = new Singleton(params)
    }
    return this.instance
  }
  // other methods...
}

ログイン後にコピー
ログイン後にコピー
  • クラスは、一意に共有可能なインスタンスを保存するための静的プロパティを定義する必要があります。

キーワード static は、インスタンス オブジェクトがクラスのインスタンスではなく、クラス定義自体に関連付けられていることを意味します。

  • クラスのコンストラクターはプライベートとしてマークされる必要があります。クラスのインスタンスを取得する唯一の方法は、静的メソッド getInstance を呼び出すことです。
const instance = Singleton.getInstance({ authorName: "Sidali Assoul" })


// let's imagine
const instance1 = Singleton.getInstance({ authorName: "Sidali Assoul" }) // "Sidali Assoul"
const instance2 = Singleton.getInstance({ authorName: "John Doe" }) // "Sidali Assoul"

ログイン後にコピー
ログイン後にコピー

Singleton クラスに関連付けられた静的メソッド getInstance を呼び出すことで、上記のクラスを利用できます。

getInstance メソッドは、コードベースの異なる場所でクラスを複数回インスタンス化した場合でも、常に同じインスタンスを取得することを保証します。

Singleton Design Pattern: Managing Global States in Your Applications

したがって、両方の変数 (instance1 と instance2) は同じシングルトン インスタンスを共有します。

最初の実践的なシナリオ

Prisma は、JavaScript エコシステムでよく知られた ORM です。アプリケーションで Prisma を使用するには、PrismaClient をインポートし、そこからオブジェクトをインスタンス化する必要があります。

class Singleton {
  private static instance: Singleton
  // other properties...
  public authorName: string

  private constructor({ authorName }: { authorName: string }) {
    this.authorName = authorName
  }

  public static getInstance(params) {
    if (!this.instance) {
      this.instance = new Singleton(params)
    }
    return this.instance
  }
  // other methods...
}

ログイン後にコピー
ログイン後にコピー

Prisma クライアントは、遅延的な方法で、つまり、最初にエンティティのクエリまたは変更を試みたときにのみ、データベースに接続します。

const instance = Singleton.getInstance({ authorName: "Sidali Assoul" })


// let's imagine
const instance1 = Singleton.getInstance({ authorName: "Sidali Assoul" }) // "Sidali Assoul"
const instance2 = Singleton.getInstance({ authorName: "John Doe" }) // "Sidali Assoul"

ログイン後にコピー
ログイン後にコピー

prismaClient がファイルにインポートされるたびに、PrismaClient から新しいインスタンスが作成されます。したがって、これらのインスタンスを使用するたびに、多くのデータベース接続が確立されます。

import { PrismaClient } from "@prisma/client"

export const prismaClient = new PrismaClient()

ログイン後にコピー

データベースは通常、限られた数の接続しか処理できないため、多数のオープンデータベース接続はアプリケーションのパフォーマンスを低下させ、データベースのシャットダウンにつながる可能性もあります。

シングルトン デザイン パターン は、PrismaClient クラスのインスタンスが複数存在することを回避し、PrismaClientSingleton.getInstance() 静的メソッド経由でインスタンスにアクセスするための単一ポイントを提供することで、このような問題を防ぐのに役立ちます。

import { prismaClient } from "@/db"

const users = await prismaClient.user.findMany() // query on the users table

ログイン後にコピー

2 番目の実践的なシナリオ

これから説明するもう 1 つの実際的なシナリオは、メモリ内レート リミッター サービスです。

ユーザーやハッカーは、特定のエンドポイントに大量のリクエストを送信することで、そのエンドポイントにスパムを送信する可能性があります。これにより、脆弱性、予期せぬコスト、またはサーバー障害が発生する可能性があります。

これを防ぐために、基本的なインメモリ レート リミッター サービスを実装できます。

サービスは、特定のタイミング ウィンドウ間隔 (たとえば、60 秒) の間、IP アドレスごとのリクエストの数を制限する必要があります。

export const prismaClient = new PrismaClient() // a new instance is created every time it gets imported then used.

ログイン後にコピー

RateLimiterService クラスは、指定されたタイミング ウィンドウ内で IP アドレス (マップ キー) によって識別される特定のユーザーによって行われたリクエスト (requests[ip].count) の数を追跡するマップを保存します。 (リクエスト[ip].lastRequestTime).

私たちの RateLimiterService はグローバルに使用することを目的としています。つまり、RateLimiterService がインポートされるたびに、リクエスト マップ、リミット、ウィンドウ変数で構成される内部状態値をリセットする必要はありません。

結論

シングルトン設計パターンは、アプリケーション内の共有リソースを効果的に管理するための強力なツールです

重要なポイント:

  1. シングルトンは、クラスのインスタンスが 1 つだけであることを保証し、そのインスタンスへのグローバル アクセス ポイントを提供します。
  2. データベース接続、構成設定、キャッシュなどの共有リソースの管理に役立ちます。
  3. 実際のアプリケーションには、Prisma などの ORM とのデータベース接続の最適化や、レート制限サービスの実装が含まれます。

接触

ご質問がある場合、またはさらに話し合いたい場合は、お気軽にここからご連絡ください。

コーディングを楽しんでください!

以上がシングルトン設計パターン: アプリケーションでのグローバル状態の管理の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート