2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PythonにおけるProxyパターン:アクセス制御と遅延ロードをスマートに設計する

Posted at

概要

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パターンはその知性を備えた透明な防壁として、コードに安心と拡張性をもたらす。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?