Python编程:代理模式(Proxy Pattern)

代理模式是一种结构型设计模式,它为其他对象提供一种代理以控制对这个对象的访问。代理模式在不改变原始类代码的情况下,通过引入代理类来间接访问原始类。

代理模式的基本结构

代理模式通常包含以下角色:

  • Subject(抽象主题):定义真实主题和代理主题的共同接口

  • RealSubject(真实主题):实现真实业务逻辑的类

  • Proxy(代理):包含对真实主题的引用,可以控制对真实主题的访问

Python实现示例

2.1 基本代理模式实现

from abc import ABC, abstractmethod

# 抽象主题
class Subject(ABC):
    @abstractmethod
    def request(self):
        pass

# 真实主题
class RealSubject(Subject):
    def request(self):
        print("RealSubject: 处理请求")

# 代理
class Proxy(Subject):
    def __init__(self, real_subject: RealSubject):
        self._real_subject = real_subject

    def request(self):
        if self.check_access():
            self._real_subject.request()
            self.log_access()

    def check_access(self):
        print("Proxy: 检查访问权限")
        return True

    def log_access(self):
        print("Proxy: 记录请求日志")

# 客户端代码
def client_code(subject: Subject):
    subject.request()

if __name__ == "__main__":
    print("直接访问真实对象:")
    real_subject = RealSubject()
    client_code(real_subject)

    print("\n通过代理访问:")
    proxy = Proxy(real_subject)
    client_code(proxy)

2.2 虚拟代理实现(延迟加载)

class HeavyResource:
    """一个创建成本很高的资源"""
    def __init__(self):
        print("加载重量级资源...")
        # 模拟耗时操作
        import time
        time.sleep(2)
        self.data = "重量级数据"
    
    def process(self):
        print(f"处理: {self.data}")

class HeavyResourceProxy:
    """虚拟代理,实现延迟加载"""
    def __init__(self):
        self._real_resource = None
    
    def process(self):
        if self._real_resource is None:
            self._real_resource = HeavyResource()
        self._real_resource.process()

# 使用示例
print("使用虚拟代理:")
proxy = HeavyResourceProxy()
print("代理已创建,但重量级资源尚未加载")
# 当真正需要时才加载资源
proxy.process()

2.3 保护代理实现(访问控制)

class SensitiveData:
    """包含敏感数据的类"""
    def __init__(self):
        self.data = "这是敏感数据"
    
    def show_data(self, user):
        print(f"显示敏感数据: {self.data}")

class ProtectionProxy:
    """保护代理,控制对敏感数据的访问"""
    def __init__(self, real_data: SensitiveData):
        self._real_data = real_data
        self._allowed_users = ["admin", "root"]
    
    def show_data(self, user):
        if user in self._allowed_users:
            self._real_data.show_data(user)
        else:
            print(f"错误: 用户 {user} 无权访问敏感数据")

# 使用示例
print("\n保护代理示例:")
data = SensitiveData()
proxy = ProtectionProxy(data)

proxy.show_data("admin")  # 允许访问
proxy.show_data("guest")  # 拒绝访问

2.4 远程代理实现(简化版)

import json
from urllib.request import urlopen

# 远程服务接口
class RemoteService:
    def fetch_data(self, url):
        with urlopen(url) as response:
            return json.loads(response.read())

# 远程代理
class RemoteProxy:
    def __init__(self):
        self._cache = {}
    
    def fetch_data(self, url):
        if url not in self._cache:
            print(f"从远程获取数据: {url}")
            service = RemoteService()
            self._cache[url] = service.fetch_data(url)
        else:
            print(f"从缓存获取数据: {url}")
        return self._cache[url]

# 使用示例
print("\n远程代理示例:")
proxy = RemoteProxy()

# 第一次访问会从远程获取
data = proxy.fetch_data("https://api.github.com/users/python")
print(f"获取到 {len(data)} 条数据")

# 第二次访问会从缓存获取
data = proxy.fetch_data("https://api.github.com/users/python")
print(f"获取到 {len(data)} 条数据")

常见应用场景

  1. 虚拟代理:延迟创建开销大的对象(如图片懒加载)

  2. 保护代理:控制对原始对象的访问权限

  3. 远程代理:为远程对象提供本地代表

  4. 缓存代理:为开销大的运算结果提供临时存储

  5. 智能引用代理:在访问对象时执行额外操作(如引用计数、线程安全检查等)

优缺点

优点

  • 可以在不修改原始对象的情况下控制对它的访问

  • 可以在访问对象前后执行额外操作

  • 可以实现延迟加载和缓存,提高系统性能

  • 符合开闭原则

缺点

  • 由于增加了代理层,可能会使请求处理速度变慢

  • 实现代理模式可能会使代码变得更复杂

代理模式与其他模式的关系

  • 适配器模式:适配器改变对象的接口,而代理保持相同的接口

  • 装饰器模式:装饰器为对象添加功能,而代理控制对对象的访问

  • 外观模式:外观模式定义了一个新接口,而代理使用原始对象的接口

代理模式是Python中非常有用的设计模式,特别是在需要控制对象访问或添加额外功能而不修改原始对象时。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值