Examples of understanding with design patterns - Proxy mode (Python Edition)

代理模式: Providing a proxy to control access to the object to other objects.

In some cases, an object is not suitable or not directly refer to another object, the proxy object can play the role of intermediary between the client and the target audience.

Proxy mode is divided into:

  • Static agents
  • Dynamic Proxy

By the following three parts :

抽象角色: Business methods implemented through an interface or abstract class declaration real role.

代理角色: Implementing abstract role, the role of agents is real, abstract methods to achieve real business logic methods by role, and can attach their own operations.

真实角色: Implementing abstract role, define business logic real role to be achieved, calls for acting role.

Static agents

Before running the program, it has been determined that the agent Relations of the proxy class and delegate class is called 静态代理.

Example: Xiao Ming litigation lawyer

Litigation process can be abstracted into ILawsuitclasses, as follows:

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

Xiaoming litigants concrete, can be written as a Litigantclass, as follows:

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')     

Lawyers can be written as a Lawyerclass, as follows:

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()

Litigation process can be expressed as:

if __name__ == '__main__':
    xiaoming = Litigant('小明')       
    lawyer = Lawyer(xiaoming)       
    lawyer.submit()     # 律师提交诉讼申请
    lawyer.burden()     # 律师进行举证
    lawyer.defend()     # 律师替小明辩护
    lawyer.finish()     # 完成诉讼
    
# 输出结果
小明申请仲裁!
证据如下:XXXXXX
辩护过程:XXXXXX
诉讼结果如下:XXXXXX

Static agent strengths and weaknesses

优点: Business class only need to focus on the business logic itself, to ensure the reuse of business class.

缺点: An interface proxy object to serve only one type of object, if you want to proxy many ways, is bound to have carried the agent for each method, the static agent in the slightly larger size of the program will not be able to perform competently.

Dynamic Proxy

Agent proxy class created in the way the program is running is called 动态代理.

In other words, in this case, the proxy class is not defined in the code, but according to us in code at runtime 指示generated dynamic.

Similarly, we illustrate:

Usually we usually call the REST API might look like this:

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

For each REST operation, will have a similar code. The difference is that the API address and HTTP method (GET, POST, etc.) only. In this case, the introduction of a GetProxycan instead of us to achieve these complex work.

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

At this point, the new call as follows:

proxy = GetProxy()

# 调用API
proxy.user(123) # http://remote.server/api/user/123
proxy.resource('switch', 456) # http://remote.server/api/resource/switch/456

Visible through dynamic proxy, greatly simplifies the calling procedure.

Compared to static agent, the agent has the advantage of dynamic can easily function on the proxy class unified process , without modifying the function of each agent class.

reference

http://adolph.cc/15712984956484.html
https://blog.zhangyu.so/python/2016/02/24/design-patterns-of-python-proxy/
Here Insert Picture Description

Guess you like

Origin www.cnblogs.com/ghostlee/p/12159107.html