概要
Proxy(プロキシ)パターンは、
あるオブジェクトへのアクセスを代理で管理・制御する設計パターンであり、
キャッシュ・遅延ロード・アクセス制御・リモート通信など多様なユースケースで活用される。
本体への直接的な依存を避けつつ、必要なタイミングで処理を行ったり、追加ロジックを差し込むことが可能。
1. なぜProxyが必要か?
❌ 大きなリソースに対して常に直接アクセスするとコストが高く制御しづらい
image = HeavyImage("sample.png")
image.display()
→ ファイル読み込みや通信が即座に発生し、制御不能
✅ Proxyを挟むことで、アクセス前に条件判断・遅延処理・キャッシュなどを追加できる
image = ImageProxy("sample.png")
image.display() # 必要になるまでHeavyImageは生成されない
→ パフォーマンス・セキュリティ・拡張性を持った中間者設計が可能
2. 基本構造
✅ Subjectインターフェース(共通のAPI)
class Image:
def display(self):
raise NotImplementedError
✅ RealSubject(実体)
class HeavyImage(Image):
def __init__(self, filename):
self.filename = filename
self._load_from_disk()
def _load_from_disk(self):
print(f"[LOAD] {self.filename} をディスクから読み込み中…")
def display(self):
print(f"[DISPLAY] {self.filename} を表示中")
✅ Proxy(代理)
class ImageProxy(Image):
def __init__(self, filename):
self.filename = filename
self._real_image = None
def display(self):
if not self._real_image:
self._real_image = HeavyImage(self.filename)
self._real_image.display()
✅ 使用例
image = ImageProxy("sample.png")
print("画像オブジェクト作成(表示はまだ)")
image.display() # このとき初めてHeavyImageが生成され、表示される
出力:
画像オブジェクト作成(表示はまだ)
[LOAD] sample.png をディスクから読み込み中…
[DISPLAY] sample.png を表示中
3. Python的応用:キャッシュ付きプロキシ
class APICacheProxy:
def __init__(self, real_api):
self.real_api = real_api
self._cache = {}
def fetch(self, key):
if key in self._cache:
print("[CACHE] ヒット")
return self._cache[key]
print("[API] 通信実行")
result = self.real_api.fetch(key)
self._cache[key] = result
return result
→ APIアクセスにおけるキャッシュ戦略を簡潔に実装できる
4. 実務ユースケース
✅ 遅延ロード(Lazy Loading)
→ 実体の生成コストが高いとき、必要になるまで生成を遅延
✅ キャッシュプロキシ
→ 結果をメモリに保存して再利用(APIレスポンス、画像、テンプレート)
✅ セキュリティプロキシ
→ 特定ユーザーのみがアクセス可能な認可チェックを挿入
✅ リモートプロキシ(RPC・gRPC)
→ 実体が別プロセス/マシンにある場合、ネットワーク越しの透明な操作
5. よくある誤用と対策
❌ ProxyがSubjectと異なるインターフェースを持つ
→ ✅ 共通インターフェースを必ず実装し、クライアントコードが透過的に扱えるようにする
❌ Proxyにビジネスロジックを埋め込んで責務過多にする
→ ✅ Proxyの責務は制御・中継に限定する
❌ Proxyの存在が設計上の前提になってしまい、本体だけで動かせない
→ ✅ RealSubjectとProxyは完全に交換可能であるべき
結語
Proxyパターンとは、“制御と保護をデザインに織り込む中間者戦略”である。
- アクセスの前後に必要な処理を注入し、オブジェクト操作に柔軟性と制御性を与える
- パフォーマンス改善、セキュリティ強化、通信の透明化など、様々な現場で活用可能
- Pythonではクラスベースの明示的Proxyも、デコレータやファサード的実装でも適用できる
Pythonicとは、“アクセスを直接許さず、責任を調停すること”。
Proxyパターンはその仲介の知性を、設計の自在性として引き出す技法である。