web-dev-qa-db-ja.com

Pythonのプロキシクラスと委任の違いは何ですか?

Wiki:

プロキシは、最も一般的な形式では、何か他のインターフェースとして機能するクラスです。プロキシは、ネットワーク接続、メモリ内のラージオブジェクト、ファイル、またはコストがかかるか複製することが不可能なその他のリソースにインターフェイスできます。要するに、プロキシは、背後で実際のサービングオブジェクトにアクセスするためにクライアントによって呼び出されるラッパーまたはエージェントオブジェクトです。

うーん!、コードの観点からこれはどのようになりますか?

Wiki

委任とは、特定の機能セットを提供するために別のオブジェクトに依存するオブジェクトを指します

このクラスは、たとえば、その機能を別のオブジェクトに委任します。

class CustomInt: 

    def __init__(self): 
        self.obj = int() 

    def __getattr__(self, attr): 
        return getattr(self.obj, attr)   # Delegation

それは何か他のインターフェースとして機能するクラスなので、プロキシクラスと見なすことができますか?

1
direprobs

プロキシには、アクションを転送する以外の機能はありません。デリゲートするクラスは、独自の機能も追加します。
事実上、代理人は委任の特殊なケースです。
@ Julesが言ったように、あなたの例はプロキシの1つです。

2
jwenting

はい。クラスはプロキシであり、これは動的言語でプロキシを実装するために使用される一般的なパターンです(静的言語では、各メソッドは通常個別に転送する必要があります)。プロキシは通常、プロキシするオブジェクトの動作も微妙に変更します(たとえば、特定のメソッドへのアクセスの防止、別のプロセスまたは別のマシンでのターゲットオブジェクトのホストなど)。

1
Jules

単純なプロキシを実装すると、次のようになります。

# Simple demonstration of the Proxy pattern.

class Implementation:
    def f(self):
        print("Implementation.f()")
    def g(self):
        print("Implementation.g()")
    def h(self):
        print("Implementation.h()")

class Proxy:
    def __init__(self):
        self.__implementation = Implementation()
    # Pass method calls to the implementation:
    def f(self): self.__implementation.f()
    def g(self): self.__implementation.g()
    def h(self): self.__implementation.h()

p = Proxy()
p.f(); p.g(); p.h()

実装がプロキシと同じインターフェースを持つ必要はありません。 Proxyがメソッド呼び出しを参照しているクラスを何らかの形で「代弁」している限り、基本的な考え方は満たされます(このステートメントはGoFでのProxyの定義と矛盾していることに注意してください)。ただし、プロキシが呼び出す必要のあるすべてのメソッドを実装が強制的に実行できるように、共通のインターフェースを用意すると便利です。

もちろん、Pythonにはデリゲートメカニズムが組み込まれているため、プロキシの実装がさらに簡単になります。

# Simple demonstration of the Proxy pattern.

class Implementation2:
    def f(self):
        print("Implementation.f()")
    def g(self):
        print("Implementation.g()")
    def h(self):
        print("Implementation.h()")

class Proxy2:
    def __init__(self):
        self.__implementation = Implementation2()
    def __getattr__(self, name):
        return getattr(self.__implementation, name)

p = Proxy2()
p.f(); p.g(); p.h();

getattr()を使用する利点は、Proxy2が完全に汎用的であり、特定の実装に関連付けられていないことです(Javaでは、これと同じことを実現するためにかなり複雑な「動的プロキシ」が発明されました)。

0
Humoyun Ahmad