【五】Python 代理模式

文章目录

  • 5.1 代理模式概述
    • 5.1.1 代理介绍
    • 5.1.2 代理模式的作用
  • 5.2 代理模式的UML类图
  • 5.3 了解不同类型的代理
    • 5.3.1虚拟代理
    • 5.3.2 远程代理
    • 5.3.3 保护代理
    • 5.3.4 智能代理
  • 5.4 现实世界中的代理模式
    • 5.5 代理模式的优点
    • 5.6 门面模式和代理模式之间的比较

5.1 代理模式概述

5.1.1 代理介绍

代理通常就是一个介于请求方和提供方之间的中介系统。
在设计模式的上下文中,代理是充当实际对象接口的类。对象类型可以是多样化的,例如网络连接、内存和文件中的大对象,等等。简而言之,代理就是封装实际服务对象的包装器或代理人。代理可以为其包装的对象提供附加功能,而无需更改对象的代码。

5.1.2 代理模式的作用

代理模式的主要目的是为其他对象提供一个代理者或占位符,从而控制对实际对象的访问。
概括来说可以归纳为以下几个方面:

  • 它能够以更简单的方式表示一个复杂的系统。例如,涉及多个复杂计算或过程的系统应该提供一个更简单的接口,让它充当客户端的代理。
  • 它提高了现有的实际对象的安全性。在许多情况下,都不允许客户端直接访问实际对象。这是因为实际对象可能受到恶意活动的危害。这时候,代理就能起到抵御恶意活动的盾牌作用,从而保护了实际的对象。
  • 它为不同服务器上的远程对象提供本地接口。一个明显的例子是客户端希望在远程系统上运行某些命令的分布式系统,但客户端可能没有直接的权限来实现这一点。因此它将请求转交给本地对象(代理),然后由远程机器上的代理执行该请求。
  • 它为消耗大量内存的对象提供了一个轻量级的句柄。有时,你可能不想加载主要对象,除非它们真的有必要。这是因为实际对象真的很笨重,可能需要消耗大量资源。一个典型的例子是网站用户的个人简介头像。你最好在列表视图中显示简介头像的缩略图,当然,为了展示用户简介的详细介绍,你就需要加载实际图片了。

让我们通过一个简单的例子来理解该模式。
其中Actor 是被代理的对象。代理对象Agent 用于查看Actor是否正处于忙碌状态。如果Actor 正忙,则调用Actor().occupied()方法;如果Actor不忙,则返回Actor().available()方法。

class Actor(object):
    def __init__(self):
        self.isBusy = False
    def occupied(self):
        self.isBusy = True
        print(type(self).__name__, "Actor被占用")

    def available(self):
        self.isBusy = False=
        print(type(self).__name__, "Actor空闲")
    def getStatus(self):
        return self.isBusy
class Agent(object):
    def __init__(self):
        self.principal = None
    def work(self):
        self.actor = Actor()
        if self.actor.getStatus():
            self.actor.occupied()
        else:
            self.actor.available()
if __name__ == '__main__':
    r = Agent()
    r.work()

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

  • 它为其他对象提供了一个代理,从而实现了对原始对象的访问控制。
  • 它可以用作一个层或接口,以支持分布式访问。
  • 它通过增加代理,保护真正的组件不受意外的影响。

5.2 代理模式的UML类图

现在,我们可以借助于图5-1中的UML图来探讨代理模式。正如我们在上一段中所介
绍的那样,代理模式有3个主要角色:制作公司、经纪人和演员。下面,让我们把这些角
色放入一个UML图中,看看这些类如何关联:

在这里插入图片描述

通过观察这个UML图,你会发现这个模式有下述3个主要的参与者。
代理:它维护一个引用,允许代理(Proxy)通过这个引用来访问实际对象。它提供了一个与主题 (Subject)相同的接口,以便代理可以替换真实的主题。代理还负责创建和删除真实主题(RealSubject)。
主题:它定义了RealSubject 和Proxy的公共接口。以Proxy和RealSubject的形式实现主题(Subject),使用 RealSubject 的任何地方都可以使用代理(Proxy)。
真实主题:它定义代理(Proxy)所代表的真实对象
从数据结构的角度来看,UML图可以表示如下。

  • 代理:它是一个控制对 RealSubject 类访问的类。它处理客户端的请求,负责创建或删除 RealSubject。

  • 主题/真实主题:主题是定义真实主题(RealSubject)和代理(Proxy)相类似的接口。RealSubject 是 Subject 接口的实际实现。它提供了真正的功能,然后由客户端使用。

  • 客户端:它访问要完成工作的 Proxy类。Proxy类在内部控制对 RealSubject的访问,并引导客户端(client)所请求的工作。

5.3 了解不同类型的代理

在许多常见的情形中,都会用到代理。在本章开头部分,我们已经对部分情形进行了讨论。根据代理的使用方式,我们可以将它们分为虚拟代理、远程代理、保护代理和智能

代理。在本小节中,我们将会进行更加深入的探讨。

5.3.1虚拟代理

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

5.3.2 远程代理

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

5.3.3 保护代理

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

5.3.4 智能代理

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

5.4 现实世界中的代理模式

我们将通过付款用例来展示代理模式的现实应用场景。让我们假设,你在商场溜达,看中了一件漂亮的牛仔衫。你想买这件衬衫,但手里的现金却不够了。
这要是在不久以前,你可以去 ATM 取钱,然后来到商场付款。在更早的时候,通常使用的是银行支票,这样你就必须去银行提款,然后再回商场付款。
得益于银行业务的发展,后来出现了一种称为借记卡的东西。所以现在,你买东西的时候,只要在商家刷一下借记卡,这笔钱就会划入商家的账户,从而完成支付。
下面,我们利用 Python v3.5来开发一个应用程序,实现上述示例。首先从客户端开始:你去了商场,现在想买一件漂亮的牛仔衫。让我们看看如何编写客户端代码。

  • 你的行为由类You(即客户端)来表示。
  • 为了购买衬衫,该类提供了make payment()方法
  • 特殊方法_init()会调用代理并将其实例化。
  • makepayment()方法在内部调用代理的方法进行付款。
  • 如果付款成功,将返回 del()方法。
class You:
    def __init__(self):
        print("You::Lets buy the Denim shirt")
        self.debitCard= DebitCard()
        self.isPurchased = None
    def make_payment(self):
        self.isPurchased = self.debitCard.do_pay()
    def __del__(self):
        if self.isPurchased:
            print("You::Wow! Denim shirt is Mine :-)")
        else:
            print("You::I should earn more :(")
you=You()
you.make_payment()

现在让我们讨论一下主题。我们知道,主题是由代理和真实主题实现的接口。

  • 在这个例子中,主题是Payment类。它是一个抽象基类,代表一个接口。
  • 付款具有一个do_pay()方法,该方法需要借助代理和真实主题来实现。
    下面我们通过具体的代码来考察这些方法:
from abc import ABCMeta,abstractmethod
class Payment(metaclass=ABCMeta):
	@abstractmethod
	def do_pay(self):
		pass

在这个场景中,我们还开发了代表真实主题的Bank类:

  • Bank实际完成从你的账户向商家账户划账的工作。
  • Bank 提供了多个方法来处理付款。代理使用setCard()方法将借记卡详细信息
    发送给银行。
  • __getAccount()方法是Bank的私有方法,用于获取借记卡持有人的账户详细
    信息。为了简单起见,我们强制使用与账号相同的借记卡号。
  • Bank 还有__hasFunds()方法,它用来查看账户持有人在账户中是否有足够的资
    金来为衬衫付款。
  • 由Bank类(通过Payment接口)实现的do_pay()方法实际上负责根据可用资金
    向商家付款:
class Bank(Payment):
	def __init__(self):
		self.card = None
		self.account= None
	def __getAccount(self):
		self.account = self.card # Assume card number is account number
		return self.account
	def __hasFunds(self):
		print("Bank:: Checking if Account", self. __getAccount(),
		"has enough funds")
		return True
	def setCard(self, card):
		self.card = card
	def do_pay (self):
		if self.__hasFunds():
			print("Bank:: Paying the merchant")
			return True
		else:
			print("Bank:: Sorry, not enough funds!")
			return False

让我们现在来理解最后一部分,即与代理有关的部分。

  • DebitCard类是此处的代理。当你想要付款时,它会调用do_pay()方法。这是
  • 因为你不想跑去银行提款,然后再跑回商家完成支付。
  • DebitCard类充当真实主题(银行)的代理。
  • payWithCard()方法在内部控制真实主题(Bank类)对象的创建,并向银行提
    供借记卡的详细信息。
  • Bank在内部对账户进行检查并完成支付,具体如代码段所述:
class DebitCard(Payment):
	def __init__(self):
		self.bank = Bank()
	def do_pay(self):
		card = input("Proxy:: Punch in Card Number: ")
		self.bank.setCard(card)
		return self.bank.do_pay()

5.5 代理模式的优点

前面,我们已经学习了代理模式在现实世界中的工作原理,接下来让我们了解一下代
理模式的优点。

  • 代理可以通过缓存笨重的对象或频繁访问的对象来提高应用程序的性能。
  • 代理还提供对于真实主题的访问授权。因此,只有提供合适权限的情况下,这个模
    式才会接受委派。
  • 远程代理还便于与可用作网络连接和数据库连接的远程服务器进行交互,并可用于
    监视系统。

5.6 门面模式和代理模式之间的比较

门面模式和代理模式都是结构型设计模式。它们的相似之处在于,都是在真实对象的
前面加入一个代理/门面对象。但是在意图或目的方面,这两种模式的确存在差异,具体如
表5-1所示。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/245136.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

卷积神经网络(含案例代码)

概述 卷积神经网络(Convolutional Neural Network,CNN)是一类专门用于处理具有网格结构数据的神经网络。它主要被设计用来识别和提取图像中的特征,但在许多其他领域也取得了成功,例如自然语言处理中的文本分类任务。 C…

Paper Reading: (CCVC) 基于冲突的半监督语义分割跨视图一致性

目录 简介目标/动机工作重点方法CVC: 跨视图一致性CPL: 基于冲突的伪标记 实验设置comparison with SOTAAblation 总结 简介 题目:《Conflict-Based Cross-View Consistency for Semi-Supervised Semantic Segmentation》, CVPR’23, 基于冲突的半监督语…

HPM5300系列--第二篇 Visual Studio Code开发环境以及多种调试器调试模式

一、目的 在博文《HPM5300系列--第一篇 命令行开发调试环境搭建》、《HPM6750系列--第四篇 搭建Visual Studio Code开发调试环境》中我们介绍了命令行方式开发环境,也介绍了HPM6750evkmini开发板如何使用Visual Studio Code进行开发调试(其中调试方式使用…

AcWing 338. 计数问题

文章目录 题目描述问题分析代码 题目描述 AcWing 338.计数问题 给定两个整数 a a a 和 b b b, 求 a a a 和 b b b中所有数字中0~9的出现次数 数据范围&#xff1a; 0 < a, b < 100000000 输入格式&#xff1a; 输入包含多组测试数据。 每组测试数据占一行&#xff0c;包…

AI会干掉美图秀秀们吗?

网上流传着这样一个传说&#xff0c;亚洲有三大“邪术”&#xff0c;韩国整容术、日本化妆术&#xff0c;还有震惊世界的中国PS 术。虽然是网友的戏称&#xff0c;但也反映了PS美图技术在国内盛行一时。 而说起美图技术就不得不提到美图公司&#xff0c;但美图公司近些年的日子…

影视动画行业发展现状与方向:AI技术推动动画工业化体系新变革

工业化体系 是国产动画强国的必经之路 中国动画的百年历程不仅是创作者们展现艺术才华的历程&#xff0c;也是一代代中国动画人不懈追求动画工业体系建设的历程。 为什么现在的中国动画需要建立工业化体系呢&#xff1f; 举个例子&#xff0c;在建立工业化体系之前&#xff…

推荐一个小而全的第三方登录开源组件

大家好&#xff0c;我是 Java陈序员。 我们在企业开发中&#xff0c;常常需要实现登录功能&#xff0c;而有时候为了方便&#xff0c;就需要集成第三方平台的授权登录。如常见的微信登录、微博登录等&#xff0c;免去了用户注册步骤&#xff0c;提高了用户体验。 为了业务考虑…

网络基础(十):DHCP原理与配置

目录 1、DHCP的概念 2、使用DHCP的优势 3、DHCP的分配方式 4、可分配的地址信息 5、DHCP的工作原理&#xff08;租约过程&#xff09; 6、DHCP动态配置主机地址&#xff08;使用eNSP软件配置&#xff09; 1、DHCP的概念 DHCP(Dynamic HostConfiguration Protocol&#x…

SLAM学习——相机模型(针孔+鱼眼)

针孔相机模型 针孔相机模型是很常用&#xff0c;而且有效的模型&#xff0c;它描述了一束光线通过针孔之后&#xff0c;在针孔背面投影成像的关系&#xff0c;基于针孔的投影过程可以通过针孔和畸变两个模型来描述。 模型中有四个坐标系&#xff0c;分别为world&#xff0c;c…

vite(一)——基本了解和依赖预构建

文章目录 一、什么是构建工具&#xff1f;1.为什么使用构建工具&#xff1f;2.构建工具的作用&#xff1f;3.构建工具怎么用&#xff1f; 二、经典面试题&#xff1a;webpack和vite的区别1.编译方式不同2.基础概念不同3.开发效率不同4.扩展性不同5.应用场景不同6.总结&#xff…

孩子都能学会的FPGA:第三十一课——用FPGA实现SPI主机发送数据

&#xff08;原创声明&#xff1a;该文是作者的原创&#xff0c;面向对象是FPGA入门者&#xff0c;后续会有进阶的高级教程。宗旨是让每个想做FPGA的人轻松入门&#xff0c;作者不光让大家知其然&#xff0c;还要让大家知其所以然&#xff01;每个工程作者都搭建了全自动化的仿…

【Python】conda镜像配置,.condarc文件详解,channel镜像

1. conda 环境 安装miniconda即可&#xff0c;Miniconda 安装包可以到 http://mirrors.aliyun.com/anaconda/miniconda/ 下载。 .condarc是conda 应用程序的配置文件&#xff0c;在用户家目录&#xff08;windows&#xff1a;C:\users\username\&#xff09;&#xff0c;用于…

SAP PP 配置学习(一)

物料主数据 一、定义物料类型属性 未检查的外部号分配&#xff1a;这是指如果用户自己输入的物料编码超出了定义的编码范围&#xff0c;是否会提示错误。 勾上代表不检查。 用户部门&#xff1a;这里勾选需要进行维护的视图&#xff0c;如果不选择&#xff0c;那么在新建和维…

苍穹外卖项目笔记(12)— 数据统计、Excel报表

前言 代码链接&#xff1a; Echo0701/take-out⁤ (github.com) 1 工作台 需求分析和设计 产品原型 工作台是系统运营的数据看板&#xff0c;并提供快捷操作入口&#xff0c;可以有效提高商家的工作效率 接口设计 ① 今日数据接口&#xff1a; ② 订单管理接口&#xff1…

智慧灯杆技术应用分析

智慧灯杆是指在传统灯杆的基础上&#xff0c;通过集成多种先进技术实现城市智能化管理的灯杆。智慧灯杆技术应用的分析如下&#xff1a; 照明功能&#xff1a;智慧灯杆可以实现智能调光、时段控制等功能&#xff0c;根据不同的需求自动调节照明亮度&#xff0c;提高照明效果&am…

论文阅读《Parameterized Cost Volume for Stereo Matching》

论文地址&#xff1a;https://openaccess.thecvf.com/content/ICCV2023/papers/Zeng_Parameterized_Cost_Volume_for_Stereo_Matching_ICCV_2023_paper.pdf 源码地址&#xff1a;https://github.com/jiaxiZeng/Parameterized-Cost-Volume-for-Stereo-Matching 概述 现有的立体匹…

SpringBoot整合Lucene实现全文检索【详细步骤】【附源码】

笑小枫的专属目录 1. 项目背景2. 什么是Lucene3. 引入依赖&#xff0c;配置索引3.1 引入Lucene依赖和分词器依赖3.2 表结构和数据准备3.3 创建索引3.4 修改索引3.5删除索引 4. 数据检索4.1 基础搜索4.2 一个关键词&#xff0c;在多个字段里面搜索4.3 搜索结果高亮显示4.4 分页检…

数组相关的题目

数组相关的题目 128. 最长连续序列 128. 最长连续序列 题目&#xff1a;给定一个未排序的整数数组 nums &#xff0c;找出数字连续的最长序列&#xff08;不要求序列元素在原数组中连续&#xff09;的长度。 很容易就能想到要先排序&#xff0c;再进行后续的处理。有一个坑&a…

Java集合--Map

1、Map集合概述 在Java的集合框架中&#xff0c;Map为双列集合&#xff0c;在Map中的元素是成对以<K,V>键值对的形式存在的&#xff0c;通过键可以找对所对应的值。Map接口有许多的实现类&#xff0c;各自都具有不同的性能和用途。常用的Map接口实现类有HashMap、Hashtab…

交易历史记录20231206 记录

昨日回顾&#xff1a; select top 10000 * from dbo.CODEINFO A left join dbo.全部&#xff21;股20231206010101 B ON A.CODE B.代码 left join dbo.全部&#xff21;股20231206CONF D on A.CODED.代码left join dbo.全部&#xff21;股20231206 G on A.CODEG.代码 left…