前言
代理模式属于结构型模式;
在日常生活中有一些代理存在,比如:要出租房屋找房产中介代理,需要连接公司内网需要VPN代理服务器。
一、代理模式
1.概念
为其他对象提供1种代理,以控制对这个对象的访问。
2.角色
抽象实体(Subject)
实体(RealSubject)
代理(Proxy)
3.优点
远程代理:可以隐藏对象位于远程地址空间的事实
虚代理:可以进行优化,例如根据需要创建对象
保护代理:需要访问1个对象时,有一些附加的内务处理
4.应用场景
远程代理:为远程对象提供代理(Django ORM)
虚代理:根据需要创建很大的对象(浏览器无图模式)
保护代理:控制对原始对象的访问,用于不同的访问权限时(不同用户访问数据库)
5.代码
from abc import ABC, abstractmethod # 抽象实体即Subject接口:使得实体、虚代理、保护代理的方法一致,可以被高层代码(Client)统一调用 class Subject(ABC): @abstractmethod def get_content(self): pass @abstractmethod def set_content(self, content): pass # 实体:真实的、需要被代理的对象,功能为:读写1个大文件文件 class RealSubject(Subject): def __init__(self, filename): self.filename = filename f = open(self.filename, "r", encoding="utf-8") print(f"打开文件{self.filename}内容") self.content = f.read() f.close() def get_content(self): return self.content def set_content(self, content): f = open(self.filename, "w", encoding="utf-8") self.content = f.write(content) f.close() # 虚代理类:根据需要懒加载大文件内容,避免文件内容过大造成内存溢出 class VitrualProxy(Subject): def __init__(self, fname): self.fname = fname self.sub = None def get_content(self): if not self.sub: self.sub = RealSubject(filename=self.fname) return self.sub.get_content() def set_content(self, content): self.sub.set_content(content) # 保护代理类:根据用户身份、访问权限读写大文件 class ProtectedProxy(Subject): def __init__(self, fname): self.sub = RealSubject(filename=fname) def get_content(self): return self.sub.get_content() # 保护代理允许在访问1个实体对象时,有一些附加的内务处理 def set_content(self, content): # 鉴定用户身份 # 判断用户权限 raise PermissionError("无写入权限") # 高层代码(Client) if __name__ == '__main__': # 会直接打开文件 RealSubject("./test.txt") # 不会直接打开文件 vproxy = VitrualProxy("./test.txt") print(vproxy.get_content()) vproxy.set_content("A") print(vproxy.get_content()) pproxy = ProtectedProxy("./test.txt") print(pproxy.get_content()) pproxy.set_content("B")
参考