01、代理模式
--定义:为其他对象提供一个代理以控制对这个对象的访问
--应用场景:
--远程代理:为远程对象提供的代理
--虚代理:根据需要创建很大的对象
--保护代理:控制对原始对象的访问,用于对象有不同访问权限时(在权限控制上做文章)
例如:django的ORM就是远程代理。手机无图模式:根据需要访问/创建对象[点击图片才进行加载],这就是虚代理。网站角色:不同用户权限不同,这就是保护代理
--角色:
--抽象实体(Subject):统一接口
--实体(RealSubject)
--代理(Proxy)
--优点:
--远程代理:可以隐藏对象位于远程地址空间的实施
--虚代理:可以优化,例如根据要求创建对象
--保护代理:允许在访问一个对象时附加一些内务处理
--代码:
from abc import *
# 被代理对象抽象类
class Subject(metaclass=ABCMeta):
@abstractmethod
def get_content(self):
pass
@abstractmethod
def set_content(self):
pass
# 具体被代理的对象:[这里设置]被代理对象可以返回和设置对象的内容,类似于数据库和网站的访问
class RealSubject(Subject):
def __init__(self, filename):
self.filename = filename
f = open(self.filename, 'r', encoding='utf8')
print("开始读取文件")
self.content = f.read()
f.close()
def get_content(self):
return self.content
def set_content(self, content):
f = open(self.filename, 'w', encoding='utf8')
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):
if not self.subj:
self.subj = RealSubject(self.filename)
return self.subj.set_content()
# 保护代理:这里模拟只有get权限,没有set权限
class ProtectProxy(Subject):
def __init__(self, filename):
self.subj = RealSubject(filename)
def get_content(self):
return self.subj.get_content()
def set_content(self):
raise PermissionError("没有权限")
""" 这里远程代理没有实现,无远端服务器
subj = RealSubject("test.txt")
# 这里subj读取文件在__init__函数中执行,不论get_content是否执行,只要对象一初始化subj属性都会占用大量空间
# 虚代理:可以通过一层封装在get_content()阶段获取文件流,避免对象在初始化时占用过多的空间
subj.get_content()
"""
""" 虚代理
subj = VirtualProxy("test.txt")
print(subj.get_content())
"""
# 保护代理
subj = ProtectProxy("test.txt")
print(subj.get_content())
subj.set_content()
02、责任链模式
--定义:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,知道有一个对象处理该请求为止
--角色:
--抽象处理者(Handler)
--具体处理者(ConcreteHandler)
--客户端(Client)
注:java spring注解,python django中的装饰器都有类似功能
注:公司请假,1 2天请假可以通过部门上级主管直接审批,请3 4天可以通过更高级主管审批,请10可能就只能总经理审批,再多就只能离职。这种请假的审批链条可能就需要我们自己来设计,一开始给谁审批不确定,只有当请假的天数确定下来了以后才能决定传递给谁,这个责任链中谁都有可能来审批这个请求
注:上述可以通过if实现,但是这属于强耦合代码改动影响可能会非常大
--适用场景:
--有多个对象可以处理一个请求
--在不明确接受者的情况下,向多个对象中的一个提交一个请求
--优点:
--降低耦合度:一个对象不知道是其他哪一个对象处理的请求
--代码:
from abc import *
class Handler(metaclass=ABCMeta):
@abstractmethod
def handle_leave(self, day):
pass
# 经理
class GeneralManager(Handler):
def handle_leave(self, day):
if day <= 10:
print("总经理准假%d天" % day)
else:
print("你还是辞职吧")
# 部门主管
class DepartmentManager(Handler):
def __init__(self):
self.next = GeneralManager()
def handle_leave(self, day):
if day <= 5:
print("部门主管准假%d天" % day)
else:
print("部门主管职权不足")
self.next.handle_leave(day)
# 项目主管
class ProjectDirector(Handler):
def __init__(self):
self.next = DepartmentManager()
def handle_leave(self, day):
if day <= 1:
print("项目主管准假%d天" % day)
else:
print("项目主管职权不足")
self.next.handle_leave(day)
# 这里不需要给高级主管发送请求,只需要给第一级主管发送请求即可
day = 7
h = ProjectDirector()
h.handle_leave(day)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
项目主管职权不足
部门主管职权不足
总经理准假7天