前言

代理模式属于结构型模式;

在日常生活中有一些代理存在,比如:要出租房屋找房产中介代理,需要连接公司内网需要VPN代理服务器。

一、代理模式

1.概念

为其他对象提供1种代理,以控制对这个对象的访问。

2.角色

抽象实体(Subject)

实体(RealSubject)

代理(Proxy)

3.优点

远程代理:可以隐藏对象位于远程地址空间的事实

虚代理:可以进行优化,例如根据需要创建对象

保护代理:需要访问1个对象时,有一些附加的内务处理

4.应用场景

远程代理:为远程对象提供代理(Django ORM)

虚代理:根据需要创建很大的对象(浏览器无图模式)

保护代理:控制对原始对象的访问,用于不同的访问权限时(不同用户访问数据库)

5.代码

 

from abc import ABC, abstractmethod


# 抽象实体即Subject接口:使得实体、虚代理、保护代理的方法一致,可以被高层代码(Client)统一调用
class Subject(ABC):
    @abstractmethod
    def get_content(self):
        pass

    @abstractmethod
    def set_content(self, content):
        pass


# 实体:真实的、需要被代理的对象,功能为:读写1个大文件文件
class RealSubject(Subject):
    def __init__(self, filename):
        self.filename = filename
        f = open(self.filename, "r", encoding="utf-8")
        print(f"打开文件{self.filename}内容")
        self.content = f.read()
        f.close()

    def get_content(self):
        return self.content

    def set_content(self, content):
        f = open(self.filename, "w", encoding="utf-8")
        self.content = f.write(content)
        f.close()


# 虚代理类:根据需要懒加载大文件内容,避免文件内容过大造成内存溢出
class VitrualProxy(Subject):
    def __init__(self, fname):
        self.fname = fname
        self.sub = None

    def get_content(self):
        if not self.sub:
            self.sub = RealSubject(filename=self.fname)
        return self.sub.get_content()

    def set_content(self, content):
        self.sub.set_content(content)


# 保护代理类:根据用户身份、访问权限读写大文件
class ProtectedProxy(Subject):
    def __init__(self, fname):
        self.sub = RealSubject(filename=fname)

    def get_content(self):
        return self.sub.get_content()

    # 保护代理允许在访问1个实体对象时,有一些附加的内务处理
    def set_content(self, content):
        # 鉴定用户身份
        # 判断用户权限
        raise PermissionError("无写入权限")


# 高层代码(Client)
if __name__ == '__main__':
    # 会直接打开文件
    RealSubject("./test.txt")
    # 不会直接打开文件
    vproxy = VitrualProxy("./test.txt")
    print(vproxy.get_content())
    vproxy.set_content("A")
    print(vproxy.get_content())

    pproxy = ProtectedProxy("./test.txt")
    print(pproxy.get_content())
    pproxy.set_content("B")

 

参考

posted on 2024-02-17 21:02  Martin8866  阅读(9)  评论(0编辑  收藏  举报