0
0

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が必要か?

❌ オブジェクトの生成やアクセスがコスト高で、そのまま使えない

image = RealImage("large_image.jpg")  # 読み込みが重い
image.display()

常に生成されると、パフォーマンスやセキュリティに問題が出る


✅ 実体の代わりにProxyを用意し、必要に応じて生成・制御する

image = ProxyImage("large_image.jpg")
image.display()  # 必要になった時点で実体生成

必要なときだけ遅延初期化、アクセス前に追加ロジックを挿入可能


2. 基本構造

✅ Subject(共通インターフェース)

class Image:
    def display(self):
        raise NotImplementedError

✅ RealSubject(実体)

class RealImage(Image):
    def __init__(self, filename):
        self.filename = filename
        self.load_from_disk()

    def load_from_disk(self):
        print(f"ロード中: {self.filename}")

    def display(self):
        print(f"表示中: {self.filename}")

✅ Proxy(代理人)

class ProxyImage(Image):
    def __init__(self, filename):
        self.filename = filename
        self._real_image = None

    def display(self):
        if self._real_image is None:
            self._real_image = RealImage(self.filename)
        self._real_image.display()

✅ 使用例

image = ProxyImage("large_image.jpg")
print("インスタンスは生成されたが、まだ表示されていない")
image.display()  # この時点でロードが走る

出力:

インスタンスは生成されたが、まだ表示されていない  
ロード中: large_image.jpg  
表示中: large_image.jpg

3. Python的応用:属性アクセスをフックするダイナミックProxy

class AccessLogger:
    def __init__(self, target):
        self._target = target

    def __getattr__(self, name):
        print(f"[ACCESS] {name}")
        return getattr(self._target, name)
class User:
    def __init__(self, name):
        self.name = name

user = AccessLogger(User("Alice"))
print(user.name)

属性アクセス・メソッド呼び出しを動的にハンドル可能


4. 実務ユースケース

✅ 遅延初期化(Lazy Initialization)

画像・動画・設定ファイルなど重いリソースの後読み


✅ キャッシュプロキシ

→ APIレスポンスや計算結果をProxyでキャッシュし再利用


✅ アクセス制御(セキュリティ・認証)

→ 認可されたユーザーのみ内部処理を実行


✅ ロギング・モニタリング・レート制限

→ 各操作前にログを取ったりアクセス数を監視


5. よくある誤用と対策

❌ Proxyの責務が肥大化して本体以上に複雑に

→ ✅ 責任は最小限(“前段処理” のみに)限定する


❌ Proxyの存在がクライアントから透過的でない

→ ✅ インターフェースを一致させ、クライアントの認識を変えない


❌ Proxyを重ねすぎてデバッグが困難に

→ ✅ ログ・デバッグ用Proxyと、本番用Proxyを分離する設計に


結語

Proxyパターンとは、“アクセスをコントロールする知的な代理人” を設計することである。

  • 実体に手を触れず、生成・実行・アクセスをコントロール可能
  • セキュリティ、パフォーマンス、責務分離の観点で実務でも極めて有用
  • Pythonでは __getattr____proxy__ 的挙動で、動的かつ柔軟に表現可能

Pythonicとは、“本質に触れずに表現の制御を委ねること”。
Proxyパターンはその緩やかな知性を、設計の制御点として定義する技法である。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?