设计模式05、代理模式 责任链模式

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天
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值