Summer SALE
Proxy

Proxy を Python で

Proxy 構造に関するデザインパターンの一つで クライアントが使う本物のサービス・オブジェクトの代理として機能するオブジェクト プロキシー を提供します プロキシーは アクセス制御 キャッシングなど 何らかの作業を行なった後 リクエストをサービス・オブジェクトに渡します

プロキシー・オブジェクトはサービスと同じインターフェースを持ち クライアントにとっては 本物のオブジェクトと交換可能です

複雑度

人気度

使用例 Proxy パターンは ほとんどの Python アプリケーションにおいては あまり見かけませんが いくつかの特殊なケースでは便利です 何らかの既存クラスのオブジェクトに何らかの振る舞いを追加したいがクライアント・コードには手を加えたくない時 かけがえのないものです

見つけ方 プロキシーは 実際の作業はすべて他のオブジェクトに委任します プロキシーがサービスのサブクラスである場合を除き プロキシーのメソッドのそれぞれは 最終的にはサービス・オブジェクトを参照するはずです

概念的な例

この例は Proxy デザインパターンの構造を説明するためのものです 以下の質問に答えることを目的としています

  • どういうクラスからできているか
  • それぞれのクラスの役割は
  • パターンの要素同士はどう関係しているのか

main.py: 概念的な例

from abc import ABC, abstractmethod class Subject(ABC): """ The Subject interface declares common operations for both RealSubject and the Proxy. As long as the client works with RealSubject using this interface, you'll be able to pass it a proxy instead of a real subject. """ @abstractmethod def request(self) -> None: pass class RealSubject(Subject): """ The RealSubject contains some core business logic. Usually, RealSubjects are capable of doing some useful work which may also be very slow or sensitive - e.g. correcting input data. A Proxy can solve these issues without any changes to the RealSubject's code. """ def request(self) -> None: print("RealSubject: Handling request.") class Proxy(Subject): """ The Proxy has an interface identical to the RealSubject. """ def __init__(self, real_subject: RealSubject) -> None: self._real_subject = real_subject def request(self) -> None: """ The most common applications of the Proxy pattern are lazy loading, caching, controlling the access, logging, etc. A Proxy can perform one of these things and then, depending on the result, pass the execution to the same method in a linked RealSubject object. """ if self.check_access(): self._real_subject.request() self.log_access() def check_access(self) -> bool: print("Proxy: Checking access prior to firing a real request.") return True def log_access(self) -> None: print("Proxy: Logging the time of request.", end="") def client_code(subject: Subject) -> None: """ The client code is supposed to work with all objects (both subjects and proxies) via the Subject interface in order to support both real subjects and proxies. In real life, however, clients mostly work with their real subjects directly. In this case, to implement the pattern more easily, you can extend your proxy from the real subject's class. """ # ... subject.request() # ... if __name__ == "__main__": print("Client: Executing the client code with a real subject:") real_subject = RealSubject() client_code(real_subject) print("") print("Client: Executing the same client code with a proxy:") proxy = Proxy(real_subject) client_code(proxy) 

Output.txt: 実行結果

Client: Executing the client code with a real subject: RealSubject: Handling request. Client: Executing the same client code with a proxy: Proxy: Checking access prior to firing a real request. RealSubject: Handling request. Proxy: Logging the time of request. 

他言語での Proxy

Proxy を C# で Proxy を C++ で Proxy を Go で Proxy を Java で Proxy を PHP で Proxy を Ruby で Proxy を Rust で Proxy を Swift で Proxy を TypeScript で