代理模式
:他のオブジェクトへのオブジェクトへのアクセスを制御するためのプロキシを提供します。
いくつかのケースでは、オブジェクトが適切でないか、または直接、別のオブジェクトを参照しない、プロキシオブジェクトは、クライアントとターゲットオーディエンスの間の仲介の役割を果たすことができます。
プロキシモードが分かれています。
- 帯電防止剤
- 動的プロキシ
次の三つの部分によって:
抽象角色
:ビジネス・メソッドは、インターフェースや抽象クラス宣言本当の役割を通じて実施しました。
代理角色
:抽象的役割を実装し、エージェントの役割は、役割によって、実際のビジネス・ロジック・メソッドを達成するために本物の、抽象メソッドで、自分の業務を添付することができます。
真实角色
:抽象的役割を実装し、ビジネスロジック本当の役割を達成することが役割を演技へのコールを定義します。
帯電防止剤
プログラムを実行する前に、プロキシクラスとデリゲートクラスのエージェント・リレーションズが呼び出されることが決定されています静态代理
。
例:暁明訴訟専門の弁護士
訴訟プロセスがに抽象化することができILawsuit
、次のように、クラス:
import abc
class ILawsuit(metaclass=abc.ABCMeta):
@abc.abstractmethod
def submit(self): # 提交申请
pass
@abc.abstractmethod
def burden(self): # 进行举证
pass
@abc.abstractmethod
def defend(self): # 开始辩护
pass
@abc.abstractmethod
def finish(self): # 诉讼完成
pass
暁明訴訟当事者のコンクリートは、のように書くことができLitigant
、次のように、クラス:
class Litigant(ILawsuit): # 继承于ILawsuit
def __init__(self, name):
self.name = name
def submit(self):
print(f'{self.name}申请仲裁!')
def burden(self):
print('证据如下:XXXXXX')
def defend(self):
print('辩护过程:XXXXXX')
def finish(self):
print('诉讼结果如下:XXXXXX')
弁護士は次のように記述することができLawyer
、次のように、クラス:
class Lawyer(ILawsuit): # 继承于ILawsuit
def __init__(self, litigant):
self.litigant = litigant # 具体诉讼人
def submit(self):
self.litigant.submit()
def burden(self):
self.litigant.burden()
def defend(self):
self.litigant.defend()
def finish(self):
self.litigant.finish()
訴訟プロセスは以下のように表すことができます。
if __name__ == '__main__':
xiaoming = Litigant('小明')
lawyer = Lawyer(xiaoming)
lawyer.submit() # 律师提交诉讼申请
lawyer.burden() # 律师进行举证
lawyer.defend() # 律师替小明辩护
lawyer.finish() # 完成诉讼
# 输出结果
小明申请仲裁!
证据如下:XXXXXX
辩护过程:XXXXXX
诉讼结果如下:XXXXXX
静的エージェントの強みと弱み
优点
:ビジネスクラスは、ビジネスクラスの再利用を確保するために、ビジネスロジックそのものに焦点を当てる必要があります。
缺点
:プロキシ多くの方法にしたい場合はアンインターフェイスプロキシオブジェクトは、オブジェクトの一種類のみを提供するためには、各メソッドのエージェントを実行しているにバインドされ、プログラムの少し大きめのサイズの帯電防止剤は、有能実行することはできません。
動的プロキシ
プログラムが実行されているようにして作成されたエージェントのプロキシクラスが呼び出されます动态代理
。
換言すれば、この場合には、プロキシクラスは、コードで定義されていないが、実行時にコードに米国に従って指示
生成された動的。
同様に、我々は示しています。
通常、我々は通常、次のようになりますREST APIを呼び出します。
import urllib
import json
def fetch_resource(resource_id):
opener = urllib.urlopen('http://remote.server/api/resource/' + resource_id)
if opener.code != 200:
raise RuntimeError('invalid return code!')
content = opener.read()
try:
return json.loads(content)
except ValueError:
return content
各REST操作については、同様のコードを持っています。違いは、APIアドレスとHTTPメソッド(GET、POSTなど)のみ。この場合、導入のGetProxy
代わりに、私たちの缶は、これらの複雑な作業を実現しています。
import urllib
import json
class GetProxy(object):
def __getattr__(self, api_path):
def _rest_fetch(*paras):
opener = urllib.urlopen('http://remote.server/api/' + api_path + '/' + '/'.join(resource_id))
if opener.code != 200:
raise RuntimeError('invalid return code!')
content = opener.read()
try:
return json.loads(content)
except ValueError:
return content
return _rest_fetch
この時点で、新しいコールは次の通り:
proxy = GetProxy()
# 调用API
proxy.user(123) # http://remote.server/api/user/123
proxy.resource('switch', 456) # http://remote.server/api/resource/switch/456
動的プロキシを通して見える、非常呼び出し手順を単純化します。
静的剤と比較して、薬剤は、動的の利点ができた簡単プロキシクラス統一プロセスで機能各エージェントクラスの機能を変更することなく、。
参照
http://adolph.cc/15712984956484.html
https://blog.zhangyu.so/python/2016/02/24/design-patterns-of-python-proxy/