概要
Proxy(プロキシ)パターンは、
あるオブジェクトへのアクセスを制御するための**「代理人」オブジェクト**を設け、
本体の機能に対して、前処理・後処理・キャッシュ・ロギング・遅延実行などを挿入できる設計パターンである。
「アクセスされる側の責任」を変更することなく、
周囲の制御ロジックを安全かつ明快に構築可能な点が最大の特長。
1. なぜProxyが必要か?
❌ 本体オブジェクトが過剰に露出している
db = RealDatabase()
db.query("SELECT * FROM users")
→ セキュリティ・キャッシュ・ログなどの関心事が未考慮
✅ アクセス経路にProxyを設置し、制御ロジックを挿入
db = DatabaseProxy()
db.query("SELECT * FROM users") # → ログ/キャッシュ/認証の処理を追加
→ 本体はそのままに、安全で拡張可能な制御が実現可能
2. 基本構造
✅ Subject(インターフェース)
class Database:
def query(self, sql: str):
raise NotImplementedError
✅ RealSubject(実体)
class RealDatabase(Database):
def query(self, sql: str):
print(f"Executing SQL: {sql}")
✅ Proxy(代理人)
class DatabaseProxy(Database):
def __init__(self):
self._real = RealDatabase()
self._log = []
def query(self, sql: str):
print(f"[LOG] Query received: {sql}")
self._log.append(sql)
return self._real.query(sql)
✅ 使用例
db = DatabaseProxy()
db.query("SELECT * FROM users")
# → [LOG] Query received: SELECT * FROM users
# → Executing SQL: SELECT * FROM users
3. Python的応用:遅延初期化(Virtual Proxy)
class LazyLoader:
def __init__(self):
self._real = None
def operation(self):
if self._real is None:
print("Loading RealObject...")
self._real = RealObject()
self._real.operation()
class RealObject:
def operation(self):
print("Performing operation.")
obj = LazyLoader()
obj.operation() # → Loading RealObject... → Performing operation.
obj.operation() # → Performing operation.
→ 重いオブジェクトの初期化を必要時に限定できる
4. 実務ユースケース
✅ DBアクセスのラップ
→ 認証・ロギング・スロットリング・再試行処理などを追加可能
✅ ファイルや画像の遅延ロード(Virtual Proxy)
→ ファイルのメタ情報だけを表示、本体はアクセス時に読み込み
✅ アクセス制御(Protection Proxy)
→ ユーザーのロールに応じた操作の許可/拒否を仲介クラスで制御
✅ API呼び出しに対するレート制限やキャッシュ(Smart Proxy)
→ 複数の関心事(セキュリティ・パフォーマンス)を集約的に制御
5. よくある誤用と対策
❌ Proxyが本体の全機能をミラーしてしまう
→ ✅ 共通インターフェースを継承して最低限のラップにとどめる
❌ Proxy自身がロジックを持ちすぎる
→ ✅ Proxyは中継と制御の役割に集中し、実処理は本体へ委譲
❌ ProxyとDecoratorの混同
→ ✅ Proxyは本体の代替としてふるまう、Decoratorは機能拡張
結語
Proxyパターンとは、“本体を守りながら振る舞いを注入する、安全かつ柔軟な設計手法”である。
- 実オブジェクトへのアクセスを仲介することで、制御構造を一元化
- 遅延初期化・キャッシュ・ログ・制限・保護などの横断的関心事を設計的に吸収
- Pythonでは、クラス継承や動的バインディングにより、柔らかく直感的に実装可能
Pythonicとは、“見た目は変わらず、裏側で制御を整える”設計哲学であり、
Proxyパターンはその知性を備えた透明な防壁として、コードに安心と拡張性をもたらす。