ちゃんなるぶろぐ

エンジニア5年生🧑‍💻 オライリーとにらめっこする毎日。

【10分でわかる💻】TypeScriptでDesign Pattern〜Proxy Pattern〜

どうも、ちゃんなるです!

今回は、Proxy Patternを紹介します🖐️

概要

Proxy Patternは、オブジェクトにアクセスするための代理(プロキシ)オブジェクトを提供し、オリジナルオブジェクトの機能を拡張することができます。

利点は、アクセス制御やリソースの最適化などが実現できることです。

今回示すプログラムの設計

具体的なシナリオとして、APIリクエストのレート制限を実装するプロキシを作成しましょう🖐️

このプロキシは、特定の時間内に許可されるAPIリクエストの回数を制限し、それ以外の場合はアクセスをブロックします。

クラス図

以下に、Mermaid記法でのクラス図とMarkdown形式でのクラス図の説明を再出力します。

クラス図 (Mermaid記法)

サンプルコードのクラス図:Mermaid Live Editorで作成

クラス名 役割
ApiRateLimiterProxy APIリクエストのレート制限プロキシ
ApiClient APIクライアントのインターフェース
RealApiClient 実際のAPIクライアント

サンプルコード

interface ApiClient {
  request(endpoint: string): string;
}
class RealApiClient implements ApiClient {
  request(endpoint: string): string {
    // 実際のAPIリクエスト処理
    return "API response";
  }
}
class ApiRateLimiterProxy implements ApiClient {
  private requestsCount: number;
  private lastResetTime: number;

  constructor(private realApiClient: ApiClient, private maxRequests: number, private resetInterval: number) {
    this.requestsCount = 0;
    this.lastResetTime = Date.now();
  }

  request(endpoint: string): string {
    const currentTime = Date.now();

    if (currentTime - this.lastResetTime > this.resetInterval) {
      this.requestsCount = 0;
      this.lastResetTime = currentTime;
    }

    if (this.requestsCount < this.maxRequests) {
      this.requestsCount++;
      return this.realApiClient.request(endpoint);
    } else {
      throw new Error("Rate limit exceeded");
    }
  }
}

では、実際に使ってみましょう🖐️

const apiClient = new RealApiClient();
const rateLimiterProxy = new ApiRateLimiterProxy(apiClient, 3, 60 * 1000); // リクエスト制限数を3に設定
console.log(rateLimiterProxy.request("/api/some/endpoint"));
console.log(rateLimiterProxy.request("/api/some/endpoint"));
console.log(rateLimiterProxy.request("/api/some/endpoint"));
console.log(rateLimiterProxy.request("/api/some/endpoint")); // 制限超過

errorになりました👏(errorになって喜ぶなんて珍しいですが笑)

API response
API response
API response
error: Uncaught Error: Rate limit exceeded
      throw new Error("Rate limit exceeded");
...

Proxy Patternの使い道

  • アクセス制御
  • キャッシュ機能
  • リソースの遅延初期化

組み合わせられるデザインパターン

  • Decorator Pattern: 機能を追加するために、既存のクラスをラップするデザインパターン。Proxy Patternと組み合わせることで、オブジェクトへのアクセス制御と同時に、追加の機能を実装できます。

chan-naru.hatenablog.com

  • Facade Pattern: 複雑なサブシステムに対して単純なインターフェースを提供するデザインパターン。Proxy Patternと組み合わせることで、アクセス制御を行いつつ、サブシステムの利用を簡素化できます。

chan-naru.hatenablog.com

  • Adapter Pattern: 互換性のないインターフェースを統一するデザインパターン。Proxy Patternと組み合わせることで、異なるインターフェースを持つオブジェクト間でアクセス制御を行うことができます。

chan-naru.hatenablog.com

まとめ

Proxy Patternは、オブジェクトへのアクセスを制御するための代理オブジェクトを導入することで、アクセス制御やリソースの最適化などを実現できるデザインパターンです。

ファイルシステムへのアクセス制御の例を通して、Proxy Patternの使い方を理解できたでしょうか👀

ぜひ、自分のプロジェクトにProxy Patternを適用して、その効果を実感してみてください。アプリケーションのアーキテクチャがより柔軟で効率的になることでしょう👍

参考文献

www.oreilly.com

en.wikipedia.org