Proxy パターン

オブジェクトへのアクセスを代理オブジェクトが仲介し、アクセス制御やキャッシュなどの付加機能を提供するパターン

設計パターン基礎

Proxy パターンとは

Proxy パターンは、本物のオブジェクト (Real Subject) の前に代理オブジェクト (Proxy) を配置し、アクセス制御、遅延初期化、キャッシュ、ログ記録などの付加機能を透過的に提供する GoF デザインパターンである。クライアントは Proxy と Real Subject を区別せずに使える。

Proxy の種類

Proxy の種類を以下にまとめる。

種類 目的
キャッシュプロキシ 結果をキャッシュして高速化 API レスポンスのキャッシュ
保護プロキシ アクセス権限をチェック 認証・認可の検証
仮想プロキシ 重いオブジェクトの遅延初期化 画像の遅延読み込み
ログプロキシ アクセスを記録 API 呼び出しのログ
リモートプロキシ リモートオブジェクトをローカルに見せる gRPC クライアント

TypeScript での実装

TypeScript での実装のコード例を示す。

interface UserRepository {
  findById(id: string): Promise<User | null>;
}

// Real Subject
class DynamoDBUserRepo implements UserRepository {
  async findById(id: string) {
    return ddb.send(new GetCommand({ TableName: 'Users', Key: { id } }));
  }
}

// キャッシュプロキシ
class CachedUserRepo implements UserRepository {
  private cache = new Map<string, { user: User | null; expiry: number }>();

  constructor(private real: UserRepository, private ttlMs = 60000) {}

  async findById(id: string) {
    const cached = this.cache.get(id);
    if (cached && Date.now() < cached.expiry) return cached.user;

    const user = await this.real.findById(id);
    this.cache.set(id, { user, expiry: Date.now() + this.ttlMs });
    return user;
  }
}

// 使用: クライアントは Proxy と Real Subject を区別しない
const repo: UserRepository = new CachedUserRepo(new DynamoDBUserRepo());

JavaScript の Proxy オブジェクト

JavaScript には言語レベルの Proxy オブジェクトがあり、プロパティアクセスやメソッド呼び出しをインターセプトできる。

const handler: ProxyHandler<any> = {
  get(target, prop) {
    console.log(`Accessing ${String(prop)}`);
    return Reflect.get(target, prop);
  },
  set(target, prop, value) {
    console.log(`Setting ${String(prop)} = ${value}`);
    return Reflect.set(target, prop, value);
  },
};

const user = new Proxy({ name: 'Alice' }, handler);
user.name;        // "Accessing name"
user.name = 'Bob'; // "Setting name = Bob"

Vue 3 のリアクティビティシステムは Proxy で実装されている。

Decorator パターンとの違い

Decorator パターンとの違いを以下にまとめる。

パターン 目的 インターフェース
Proxy アクセス制御、遅延初期化 Real Subject と同じ
Decorator 機能の追加 (重ねがけ可能) Real Subject と同じ

Proxy は「アクセスを制御する」、Decorator は「機能を追加する」。実装は似ているが意図が異なる。

実務での活用

  • API Gateway: Lambda の前段に配置される Proxy (認証、レート制限、キャッシュ)
  • CloudFront: オリジンサーバーの前段に配置されるキャッシュプロキシ
  • RDS Proxy: Lambda と RDS の間に配置される接続プーリングプロキシ

Proxy パターンの理解を深めるには関連書籍が参考になる。

この記事は役に立ちましたか?

関連用語

関連する記事