🇨🇳🐲🎉 本网站的中文版本尚处早期开发阶段。如果您发现其中存在错字、纰漏或其他任何问题,请随时联系 [email protected] 向我反馈。
代理

代理在 Python 中的实现

代理是一种结构型设计模式 让你能提供真实服务对象的替代品给客户端使用 代理接收客户端的请求并进行一些处理 访问控制和缓存等 然后再将请求传递给服务对象

代理对象拥有和服务对象相同的接口 这使得当其被传递给客户端时可与真实对象互换

进一步了解代理模式

在 Python 中使用模式

复杂度

流行度

使用示例 尽管代理模式在绝大多数 Python 程序中并不常见 但它在一些特殊情况下仍然非常方便 当你希望在无需修改客户代码的前提下于已有类的对象上增加额外行为时 该模式是无可替代的

识别方法 代理模式会将所有实际工作委派给一些其他对象 除非代理是某个服务的子类 否则每个代理方法最后都应该引用一个服务对象

概念示例

本例说明了代理设计模式的结构并重点回答了下面的问题

  • 它由哪些类组成
  • 这些类扮演了哪些角色
  • 模式中的各个元素会以何种方式相互关联

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.

代理在其他编程语言中的实现

代理 在 Java 中的实现 代理 在 C# 中的实现 代理 在 PHP 中的实现 代理 在 Ruby 中的实现 代理 在 Swift 中的实现 代理 在 TypeScript 中的实现