Proxy パターン

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

設計パターン基礎

Proxy パターンとは

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

Proxy の種類

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

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 パターンとの違い

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

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

実務での活用

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

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

関連用語