代理模式深度指南:构建控制访问的艺术

Published: (May 20, 2026 at 09:05 PM EDT)
5 min read
Source: Dev.to

Source: Dev.to

代理模式概述

核心角色

角色说明
Subject(抽象主题)定义了 RealSubjectProxy 的公共接口
RealSubject(真实主题)真正执行业务逻辑的对象
Proxy(代理)持有 RealSubject 的引用,在需要时创建或访问真实对象
Client(客户端)通过 Proxy 与真实对象交互,感知不到真实对象的存在

典型的调用链如下:

客户端 → 本地代理 → 网络 → 远程服务

代理模式的典型应用

延迟加载(虚拟代理)

在需要访问代价高昂的资源(如远程图片)时,只有在真正需要时才创建真实对象。

class VirtualProxyImage:
    def __init__(self, url):
        self.url = url
        self._real_image = None

    def display(self):
        # 首次调用时才加载真实图片
        if not self._real_image:
            self._real_image = RealImage(self.url)
        self._real_image.display()

访问控制

代理可以在调用前进行身份验证或权限检查,类似公司门禁系统。

缓存与懒加载示例

下面的示例展示了如何使用代理实现图片的懒加载与缓存,避免重复的磁盘读取。

from abc import ABC, abstractmethod
import time

# 抽象主题
class Image(ABC):
    @abstractmethod
    def display(self):
        pass

# 真实主题
class RealImage(Image):
    def __init__(self, filename):
        self.filename = filename
        self._load_from_disk()

    def _load_from_disk(self):
        print(f"正在加载图片: {self.filename}")
        time.sleep(1)  # 模拟加载时间
        print("加载完成!")

    def display(self):
        print(f"显示图片: {self.filename}")

# 虚拟代理
class ProxyImage(Image):
    def __init__(self, filename):
        self.filename = filename
        self._real_image = None

    def display(self):
        if self._real_image is None:
            self._real_image = RealImage(self.filename)
        self._real_image.display()

# 使用示例
print("=== 第一次显示 ===")
img = ProxyImage("photo.jpg")
img.display()

print("\n=== 第二次显示 ===")
img.display()

运行结果

=== 第一次显示 ===
正在加载图片: photo.jpg
加载完成!
显示图片: photo.jpg

=== 第二次显示 ===
显示图片: photo.jpg

代理模式特性对比

特性代理模式装饰器模式
目的控制访问、延迟加载、权限校验动态添加功能、增强行为
关系替代真实对象包装真实对象
创建时机预先或运行时创建运行时包装
客户端感知无感知(透明代理)感知到额外的装饰层

实际案例

连接池(资源代理)

连接池本质上是对数据库/网络连接的代理:预先创建一定数量的连接,客户端从代理获取连接,用完后归还,而不是每次都新建。

API 限流代理

在高并发系统中,代理可以实现请求速率限制,保护后端服务不被过载。

import time

class RateLimitedProxy:
    def __init__(self, real_service, max_requests, time_window):
        self.real_service = real_service
        self.max_requests = max_requests
        self.time_window = time_window
        self.requests = []  # 记录请求时间戳

    def call(self, *args, **kwargs):
        now = time.time()
        # 清理已过期的请求记录
        self.requests = [t for t in self.requests if now - t = self.max_requests:
            raise Exception("请求过于频繁,请稍后再试")

        self.requests.append(now)
        return self.real_service.execute(*args, **kwargs)

在线考试系统中的代理

  • 检测切屏次数
  • 限制复制粘贴
  • 记录异常行为(如异常网络请求)

通过代理可以在不改动业务代码的前提下,实现上述监控与限制。

代理模式的价值

  • 解耦:将访问逻辑与业务逻辑分离
  • 增强:无感添加日志、缓存、限流等功能
  • 控制:实现访问控制、权限验证
  • 优化:通过懒加载和缓存提升性能

掌握代理模式后,你将在系统设计时拥有一件强大的利器。

后续预告

策略模式(Strategy Pattern)——让算法 interchangeable 的艺术。

结语

合理使用代理模式可以显著提升系统的性能与安全性,但切记不要过度设计。只有当真正需要控制访问或添加横切关注点时,才考虑引入代理。祝你在设计模式的学习之路上收获满满!

0 views
Back to Blog

Related posts

Read more »