时间:2023-01-14 11:32:36 | 栏目:Python代码 | 点击:次
代理模式,为其他对象提供一种代理,以此控制一个对象的访问方式。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
远程(Remote)代理:为一个位于不同的地址空间的对象提供一个局域代表对象。这个不同的地址空间可以是在本机器中,也可是在另一台机器中。远程代理又叫做大使(Ambassador
)。好处是系统可以将网络的细节隐藏起来,使得客户端不必考虑网络的存在。
虚拟(Virtual)代理:根据需要创建一个资源消耗较大的对象,使得此对象只在需要时才会被真正创建,例如:图片延迟加载。使用虚拟代理模式的好处就是代理对象可以在必要的时候才将被代理的对象加载;代理可以对加载的过程加以必要的优化。当一个模块的加载十分耗费资源的情况下,虚拟代理的好处就非常明显。
保护代理(Protection Proxy ):控制对原始对象的访问。保护代理用于对象应该有不同 的访问权限的时候。
智能引用(Smart Reference)代理:当一个对象被引用时,提供一些额外的操作,比如将对此对象调用的次数记录下来等。
实体角色:
import abc # 抽象角色 class Subject(metaclass=abc.ABCMeta): @abc.abstractmethod def get_content(self): pass @abc.abstractmethod def set_content(self, content): pass # 真实角色 class RealSubject(Subject): def __init__(self, filename): self.filename = filename f = open(self.filename, "r", encoding="utf-8") self.content = f.read() print("读取文件...") f.close() def get_content(self): return self.content def set_content(self, content): f = open(self.filename, "w", encoding="utf-8") f.write(content) f.close() # 虚代理 class VirtualProxy(Subject): def __init__(self, filename): self.filename = filename self.subj = None def get_content(self): if not self.subj: self.subj = RealSubject(self.filename) return self.subj.get_content() def set_content(self, content): if not self.subj: self.subj = RealSubject(self.filename) return self.subj.set_content(content) # 保护代理 class ProtectedProxy(Subject): def __init__(self, filename): self.filename = filename self.subj = RealSubject(self.filename) def get_content(self): return self.subj.get_content() def set_content(self, content): raise PermissionError("您的权限不够!") if __name__ == "__main__": print("--- RealSubject ---") subj = RealSubject("test.txt") # 在这里就会读取文件,并占用内存。 print(subj.get_content()) #subj.set_content("修改内容...") print("--- VirtualProxy ---") subj = VirtualProxy("test.txt") # 虚代理只有在调用 get_content 时才会读取文件,并占用内存。 #print(subj.get_content()) #subj.set_content("修改内容...") print("--- ProtectedProxy ---") subj = ProtectedProxy("test.txt") #print(subj.get_content()) #subj.set_content("修改内容...") # 保护代理这里不能进行修改,会报错。