#12 / 23
S構造DIFF
プロキシ
Proxy
本人の代わりに受付が立つ。アポ取り・身分確認・取次ぎを代行して、本人は本来の仕事に集中。
Intent · 目的
本物のオブジェクトの代理として、同じ顔つき(インタフェース)で振る舞うラッパー。本物に到達する手前で、認可・遅延読込・キャッシュ・ログ・リモート呼び出しなどを差し挟める。
Motivation · 動機
「画像を100枚並べたいけど、ページを開いた瞬間に全部読み込んだら重い」── スクロールして見えた瞬間にだけ読みたい。本物の `Image` クラスにその機能を持たせると責務が肥大化する。代わりに、同じ顔をした『代理画像』を100枚置いておき、表示要求が来た瞬間に内部で本物を呼ぶ。利用側は『代理だ』と意識する必要がない。受付係が「ちょっとお待ちを」と言ってる間に、本物に取り次いでくれている、そんなイメージ。
適用場面
- 1リモートオブジェクトをローカルのように扱いたい(リモートプロキシ)。
- 2重いオブジェクトの初期化を遅延したい(仮想プロキシ/Lazy load)。
- 3アクセス制御・認可を差し込みたい(保護プロキシ)。
- 4結果のキャッシュ、ロギング、計測を透過的に差し込みたい。
概念図
サンプルコード
interface Image { display(): void; }
class HighResImage implements Image {
constructor(private path: string){ console.log(`loading ${path}...`); }
display(){ console.log(`show ${this.path}`); }
}
class ImageProxy implements Image {
private real: HighResImage | null = null;
constructor(private path: string) {}
display(){
if (!this.real) this.real = new HighResImage(this.path);
this.real.display();
}
}
const img: Image = new ImageProxy("photo.jpg");
img.display();Pros · メリット
- +本物に手を入れずに、振る舞いを差し挟める。本人の集中を邪魔しない受付係スタイル。
- +用途が幅広い:遅延読込、認可、キャッシュ、ログ、計測、リモート呼出し。
- +クライアントから見れば本物と同じ顔。途中差し替えも容易。
Cons · デメリット
- −間接層が増えてデバッグが面倒に。スタックを覗くと『プロキシまみれ』になることも。
- −受付の権限がどんどん増えると、いつの間にか神オブジェクト化する。
- −リモートプロキシは透過的すぎて、クライアントが『これがネットワーク呼出しだと知らずに』連発し、レイテンシ事故を起こす。
関連パターン
⚔ ready to test
理解度を確かめる時間だ
3 問のクイズで、 このパターンを身体に染み込ませよう。