设计模式十:代理模式
什么是代理模式
使用代理对象在访问实际对象之前执行重要操作。
可以使用一个新的类来进行包装完成此模式。
四种类型:
远程代理:实际存在于不同地址空间的对象在本地的代理者。
虚拟代理:用于懒初始化,将一个大计算量对象的创建延迟到真正需要的时候进行。
保护代理:控制对敏感对象的访问。
智能代理:在对象被访问时执行额外的动作。
典型案例
1.使用私有网络或云搭建一个分布式系统
2.过早创建计算成本较高的对象导致应用遭受性能问题
3.检查一个用户是否有足够权限访问某个信息片段
4.使用多线程,线程安全的重任从客户端转移到应用
5.对象关系映射API
补充知识
描述符:Python中重写类属性访问方法的默认行为要使用的一种机制
_get_()、_set_()、_delete_()都是描述符
实例代码
#虚拟代理 惰性加载特性
class LazyProperty:
def __init__(self,method):
self.method = method
self.method_name = method.__name__
print('function overriden:{}'.format(self.method))
print('function name : {}'.format(self.method_name))
#重写__get__,使得只需.resource即可代替.resource()
def __get__(self,obj,cls):
#惰性加载,仅可以设置一次
if not obj:
return None
value = self.method(obj)
print('value:{}'.format(value))
#动态给类增加一个属性
setattr(obj,self.method_name,value)
return value
class Test:
def __init__(self):
self.x = 'foo'
self._resource = None
#修饰器是类,在实例化的时候会初始化
@LazyProperty
def resource(self):
print('self._resource : {}'.format(self._resource))
self._resource = tuple(range(5))
return self._resource
def main1():
t= Test()
print(t.x)
#当第一次调用的时候才会初始化_resource 属性
print('第一次调用resource')
print(t.resource)
print('第二次调用resource')
print(t.resource)
print('_resource的值',end='')
print(t._resource)
#------------------------------------------------------------------#
#防护代理
class Account:
def __init__(self):
self.money = 1000
def add(self,num):
self.money += num
print('Account add {} , remain :{}'.format(num,self.money))
def delete(self,num):
self.money -= num
print('Account delete {} , remain :{}'.format(num,self.money))
class Protect:
def __init__(self):
self.protect = Account()
#密码不要直接写在源码里,也不要写明文,加密在某个文件里最好
self.pwd = '123456'
def add(self,num):
password = input('Enter the password..')
self.protect.add(num) if password == self.pwd else print('That`s wrong')
def delete(self,num):
password = input('Enter the password..')
self.protect.delete(num) if password == self.pwd else print('That`s wrong')
def main2():
protect = Protect()
while True:
print('1.add 2.delete')
key = input('choose option:')
if key =='1':
num = input('Enter the num:')
protect.add(int(num))
elif key =='2':
num = input('Enter the num:')
protect.delete(int(num))
if __name__ == "__main__":
main1()
main2()