首頁 > web前端 > js教程 > 單例設計模式:管理應用程式中的全域狀態

單例設計模式:管理應用程式中的全域狀態

Susan Sarandon
發布: 2024-12-03 19:34:15
原創
379 人瀏覽過

您是否曾經發現自己正在處理需要在應用程式的多個部分之間共享的物件(可能是資料庫連線、WebSocket 用戶端或設定管理員)?

如何管理這樣的對象,使其在整個應用程式或進程生命週期中保持一致且可存取?這就是單例設計模式發揮作用的地方。

概述

Singleton 是一種創意設計模式,它是一類設計模式,用於處理使用new 建立物件的本機方式所帶來的不同問題。 關鍵字或運算子。

單例設計模式專注於解決兩個主要問題:

  1. 我們如何為我們的實例提供全球存取點
  2. 我們如何確保一個類別或某一特定類型的物件只有一個實例?

它可以簡化和標準化我們管理特定種類或類型的全局狀態的方式,例如資料庫連接、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

登入後複製
第二個實際場景

我們將要經歷的另一個實際場景是

記憶體中速率限制器服務

使用者或駭客可以透過向特定端點發出大量請求來向其發送垃圾郵件。這可能會導致漏洞、意外成本或伺服器故障。

為了防止這種情況,我們可以實現基本的記憶體速率限制器服務。

服務應限制特定時間視窗間隔(例如 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. 它對於管理資料庫連線、配置設定或快取等共享資源很有用。
  2. 實際應用包括優化與 Prisma 等 ORM 的資料庫連線以及實施速率限制服務。
接觸

如果您有任何疑問或想進一步討論,請隨時與我聯繫。

編碼愉快!

以上是單例設計模式:管理應用程式中的全域狀態的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板