Python代理模式——控制对象的访问一

理解代理模式

代理通常就是一个介于寻求方和需求方之间的中介系统。寻求方是发出请求的一方,而提供方是根据请求提供资源的一方。在Web世界中,它相当于代理服务器。客户端在向网站发出请求时,首先连接到代理服务器,然后向它请求诸如网页之类的资源。代理服务器在内部评估此请求,将其发送到适当的服务器,当它收到响应后,就会将响应传递给客户端。因此代理服务器可以封装请求、保护隐私,并且非常适合在分布式架构中运行。

在设计模式的上下文中,代理是充当实际对象接口的类。对象类型可以是多样化的,例如网络连接、内存和文件中的大对象;简而言之,代理就是封装实际服务对象的包装器或代理人。代理可以为其包装的对象提供附加功能,而无需更改对象的代码。代理模式的主要目的是为其他对象提供一个代理者或占位者,从而控制对实际对象的访问。

代理模式可以用于多种场景,如下所示:

1、它能够以简单的方式表示一个复杂的系统。例如,涉及多个复杂计算或过程的系统应该提供一个更简单的接口,让它充当客户端的代理。

2、他提高了现有的实际对象的安全性。在许多情况下,都不允许客户端直接访问实际对象。这是因为实际对象可能受到恶意活动的危害。这时候,代理就能起到抵御恶意活动的盾牌作用,从而保护了实际的对象。

3、它为不同服务器上的远程对象提供本地接口。一个明显的例子是客户端希望在远程系统上运行某些命令的分布式系统,但是客户端可能没有直接的权限来实现这一点。因此它将请求转交给本地对象(代理),然后有远程机器上的代理执行该请求。

4、它为大量消耗内存的对象提供一个轻量级的句柄。有时,可能不想加载主要对象,除非它们真的有必要。这是因为实际对象真的很笨重,可能需要消耗大量资源。一个典型的例子是网站用户的个人简介头像。最好在列表视图中显示简介头像的缩略图,当然,为了展示用户简介的详细介绍,就需要加载实际图片

下面我们通过生活中的一个例子来理解该模式。以演员与他的经纪人为例,当制作公司想要找演员拍电影时,它们通常会与经纪人交流,而不是直接跟演员交流。经纪人会根据演员的日程安排和其他的合约情况,来答复制作公司该演员是否有空,以及是否对该影片感兴趣。在这种情况下,制作公司并不直接找演员交涉,而是通过经纪人作为代理,处理所有与演员有关的调度和片酬问题。

class Actor(object):
    def __init__(self):
        self.is_busy = False

    def occupied(self):
        self.is_busy = True
        print(type(self).__name__, "正在忙着")

    def available(self):
        self.is_busy = False
        print(type(self).__name__, "有空")

    def get_status(self):
        return self.is_busy


class Agent(object):
    def __init__(self):
        self.principal = False

    def work(self):
        self.actor = Actor()
        if self.actor.get_status():
            self.actor.occupied()
        else:
            self.actor.available()


if __name__ == '__main__':
    r = Agent()
    r.work()

上面代码实现了这种场景,其中Actor是代理对象Agent用于查看Actor是否处于忙碌状态。如果Actor正忙,则调用Actor().occupied()方法;如果Actor不忙,则返回Actor().available()方法。

代理设计模式主要完成了以下工作:

1、它为其他对象提供了一个代理,从而实现了对原始对象的访问控制

2、它可以用作一个层或接口,以支持分布式访问

3、它通过增加代理,保护真正的组件不受意外的影响

不同类型的代理

根据代理的使用方式,我们可以将它们分为虚拟代理、远程代理、保护代理和智能代理

虚拟代理

如果一个对象实例化后会占用大量内存的话,可以先利用占位符来表示,这就是所谓的虚拟代理。例如,假设你想在网站上加载大型图片,而这个请求需要很长时间才能加载完成。通常,开发人员将在网页上创建一个占位符图标,以提示这里有图像。但是,只有当用户实际点击图标时才会加载图像,从而节省了向存储器中加载大型图像的开销。因此,在虚拟代理中,当客户端请求或访问对象时,才会创建实际对象。

远程代理

它给位于远程服务器或不同地址空间上的实际对象提供了一个本地表示。例如,你希望为应用程序建立一个监控系统,而该应用涉及多个Web服务器、数据库服务器、celery任务服务器、缓存服务器,等等。如果我们要监视这些服务器的CPU和磁盘利用率,就需要建立一个对象,该对象能够用于监视应用程序运行的上下文中,同时还可以执行远程命令以获取实际的参数值。在这种情况下,建立一个作为远程对象的本地表示的远程代理对象将可以帮助我们实现这个目标。

保护代理

这种代理能够控制RealSubject(真实主题)的敏感对象的访问。例如,在当今分布式系统的世界中,web会提供多个服务,这些服务相互协作来提供各种功能。现在,在这样的系统中,认证服务充当负责认证和授权的保护性代理服务器。在这种情况下,代理自然有助于保护网站的核心功能,防止无法识别或未授权的代理访问它们。因此,代理对象会检查调用者是否具有转发请求所需的访问权限。

智能代理

智能代理在访问对象时插入其他操作。例如。假设在系统中有一个核心组件,它将状态信息集中保存在一个地点。通常情况下,这样的组件需要被多个不同的服务调用以完成它们的任务,并且可能导致共享资源的问题。让服务之间调用核心组件不同,智能代理是内置的,并且会在访问之前检查实际对象是否被锁定,以确保没有其他对象可以更改它。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值