
代理人(代わりになるオブジェクト)を用意して、本体(実オブジェクト)へのアクセスを制御・保護・遅延するパターンがProxyパターンです。
わかりやすく例えると、有名人に直接会えないけど、秘書(Proxy)を通じてメッセージを渡すようなイメージ。
秘書が、依頼を整理したり、アクセスを制限したりしてくれるパターンです。
よく使われる場面
・アクセス制御(認可・認証)
・遅延ロード(Lazy Loading)
・キャッシュ
・リモート通信の仲介(RPC, API代理)
・ログや監査の挿入(監視)
下記の場面で使われます。
・Web API のキャッシュ層
・ORMやDBアクセスのラッパー
・React/Vue のリアクティブシステム(実は内部で Proxy が使われている)
・アクセス制限付きの設定管理(設定値の変更防止など)
サンプルコード
実際のオブジェクト
class UserData {
getSecret() {
return "🔒 秘密のデータ";
}
}
Proxy(代理人)
class UserProxy {
constructor(user, role) {
this.user = user;
this.role = role;
}
getSecret() {
if (this.role === "admin") {
return this.user.getSecret();
} else {
console.log("🚫 アクセス拒否:権限がありません");
return null;
}
}
}
使用例
const admin = new UserProxy(new UserData(), "admin");
const guest = new UserProxy(new UserData(), "guest");
console.log(admin.getSecret()); // OK
console.log(guest.getSecret()); // 拒否
ポイント解説
UserData は「実際の対象(本体)」ユーザーテーブルのモデルデータです。
UserProxy は「代理人」で、呼び出しをラップして制御する役割のクラス。
呼び出しは見た目上同じ (getSecret() でアクセス) だが、内部で制御が行われます。
ユーザータイプや権限値などで判断するシステム処理でよく使われるパターンですね。
JavaScriptのネイティブProxyを使う場合
ES6 には Proxy 機能が組み込まれており、オブジェクト操作を「横取り」して制御できます。
const user = {
name: "koji",
age: 30
};
const proxy = new Proxy(user, {
get(target, prop) {
console.log(`🕵️♂️ ${prop} にアクセス`);
return target[prop];
},
set(target, prop, value) {
if (prop === "age" && value < 0) {
throw new Error("年齢に負の値は設定できません");
}
target[prop] = value;
return true;
}
});
console.log(proxy.name); // 🕵️♂️ name にアクセス
proxy.age = 25; // OK
proxy.age = -5; // ❌ Error発生
メリット
・本体のコードを変更せずに、挙動をカスタマイズできる。
・遅延処理やキャッシュなどを後付け可能。
・セキュリティやログなど横断的関心ごと(AOP的処理)に便利。
デメリット
・間接的になるため、デバッグが難しくなる。
・オーバーヘッド(処理コスト)が増える可能性。
・多重Proxyなど複雑化しやすい。
あとがき
権限系でよく使われるProxyデザインパターンです。
データへのアクセスには必ずセキュリティが必要な時代になってきたので、
プログラミングでちゃんとインジェクション対応できるようにするのをデザインパターンで処理できるProxtパターンは、よく使うこと間違いなしですね。
0 件のコメント:
コメントを投稿