代理模式
意图:为其他对象提供一种代理以控制对这个对象的访问。在需要用比较通用和复杂的对象指针代替简单的指针的时候,使用Proxy模式。
角色:
抽象实体(Subject)
实体(RealSubject)
代理(Proxy)
适用场景:
远程代理:为远程的对象提供代理。一个对象在不同的地址空间提供局部代表。
虚代理:根据需要创建很大的对象。
保护代理:控制对原始对象的访问,用于对象有不同访问权限时。保护代理用于对象应该有不同的访问权限的时候。例如,在Choices 操作系统[ CIRM93]中KemelProxies为操作系统对象提供了访问保护。
智能指引(Smart Reference )取代了简单的指针,它在访问对象时执行一些附加操作。 它的典型用途包括:对指向实际对象的引用计数,这样当该对象没有引用时,可以自动释放它。
优点:
远程代理:可以隐藏对象位于远程地址空间的事实
虚代理:可以进行优化,例如根据要求创建对象
保护代理:允许在访问一个对象时有一些附加的内务处理
当第一次引用一个持久对象时,将它装入内存。在访问一个实际对象前,检查是否已经锁定了它,以确保其他对象不能改变它。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from abc import ABCMeta, abstractmethod class Subject(metaclass=ABCMeta): @abstractmethod def get_content(self): pass def set_content(self, content): pass #文件操作,获取文件内容和设置 class RealSubject(Subject): def __init__(self, filename): self.filename = filename print("读取%s文件内容"%filename) f = open(filename) self.content = f.read() f.close() def get_content(self): return self.content def set_content(self, content): f = open(self.filename, 'w') f.write(content) self.content = content f.close() class ProxyA(Subject): def __init__(self, filename): self.subj = RealSubject(filename) def get_content(self): return self.subj.get_content() #---虚代理 class ProxyB(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() x = ProxyB('abc.txt') """abc.txt 内文本 hello world""" #print(x.get_content()) # --保护代理 class ProxyC(Subject): def __init__(self, filename): self.subj = RealSubject(filename) def get_content(self): self.subj.get_content() def set_content(self, content): raise PermissionError filename = "abc.txt" username = input() if username!="somebody": p = ProxyC(filename) else: p = ProxyA(filename) print(p.get_content()) 代理模式