一文搞懂设计模式之代理模式

大家好,我是晴天,本周我们又见面了。本周有点发烧感冒,更文有点慢了,请大家见谅。言归正传,本周我们继续一起学习一文搞懂设计模式系列文章之代理模式。

代理模式-本文目录

什么是代理模式

我们先来看看 GoF 对代理模式的定义:

Provide a surrogate or placeholder for another object to control access to it. ——— GoF
即:代理模式为一个对象提供一种代理以控制对该对象的访问。

代理模式属于结构型设计模式,它能够代替客户向服务提供者发起请求,并且可以在请求服务提供者的前后做一些其他方面的处理。

为了便于我们的理解,接下来借助一个具体的场景理解代理模式。

场景

假设你很喜欢海外购物,喜欢购买韩国的化妆品,喜欢购买美国的生鱼片。在没有代理商的年代里,你只能亲自飞到韩国卖化妆品的店去购买化妆品,飞到美国的生鱼片店去购买生鱼片。你买完这些商品之后,回国进海关的时候,你还需要接受安检并依法补交税款,然后你才能带着这些商品回家享用。这一整个过程是相当费时而且繁琐的,每次你都难免会为出海购物而感都头疼。这时候,一个名叫“胖墩墩”的代理商出现了,他能够去韩国买对应的化妆品、去美国买你要的生鱼片并通过海关的安检带回国,然后向你出售韩国化妆品和美国生鱼片,这样就不需要你亲自出国购买而且也不需要你过海关安检,你只需要付钱给“胖墩墩”,然后在家等着收货就行了。

从这个场景中,我们看到,代理去韩国买了你想要的化妆品,去美国买了你喜欢的生鱼片,并且通过海关带回了祖国,你只需要付钱给代理,就可以在家等着收货了。我们现在就可以清晰代理是什么了,代理能够代替服务提供商(韩国化妆品店和美国生鱼片店)向你提供服务,并且还能够额外提供更多的服务(通过海关安检交税),因此在你看来,跟代理买东西和直接跟服务提供商买东西无异。

为什么需要代理模式

代理模式类图
我们来看一下代理模式的类图
首先定义一个抽象的服务提供商 shopping,它能够提供 Buy(good)购买商品的方法,它的子类有具体的韩国服务提供商和美国服务提供商,以及代理商,都需要实现 Buy(good)方法,代理商还有一个CheckIn(good)的额外方法,用于海关安检,代理商需要依赖于具体的服务提供商(韩国服务提供商和美国服务提供商)。客户端可以直接跟接口进行交互。

通过上面的场景,这个问题就很好说明了。

  1. 代理可以把原始的服务提供商封装起来,向我们提供服务
  2. 代理可以提供额外更强劲的功能
  3. 代理的使用方法和原始服务提供商无异

如何使用代理模式

下面我们把上面的场景写成代码,一起来学习一下

package mainimport "fmt"// 代理模式
// 定义需要购买的商品的结构
type Good struct {Name     stringProducer string
}// 抽象层
// 服务提供商的抽象化定义   向我们提供Buy(good) 方法
type Shopping interface {Buy(good Good)
}// 实现层
// 韩国购物
type KoreaShopping struct {
}func (k *KoreaShopping) Buy(good Good) {fmt.Println("购买了一件韩国商品:", good.Name)
}// 美国购物
type AmericaShopping struct {
}func (a *AmericaShopping) Buy(good Good) {fmt.Println("购买了一件美国商品:", good.Name)
}// 代理类,用于封装韩国购物和美国购物对象
type ShoppingProxy struct {// 继承抽象结构,用于后续传入具体韩国购物对象和美国购物对象,从而实现多态功能shopping Shopping
}func NewShoppingProxy(shopping Shopping) ShoppingProxy {return ShoppingProxy{shopping: shopping,}
}func (s *ShoppingProxy) Buy(good Good) {s.shopping.Buy(good)s.CheckIn(good)
}func (s *ShoppingProxy) CheckIn(good Good) {if good.Producer == "america" {fmt.Printf("对美国购买的商品:%v,缴税并加征%v关税\n", good.Name, "120%")} else if good.Producer == "korea" {fmt.Printf("对韩国购买的商品:%v,缴税并加征%v关税\n", good.Name, "100%")}
}// 业务逻辑层
func main() {g1 := Good{Name:     "韩国化妆品",Producer: "korea",}g2 := Good{Name:     "美国生鱼片",Producer: "america",}k_shopping := &KoreaShopping{}var shopping ShoppingProxyshopping = NewShoppingProxy(k_shopping)shopping.Buy(g1)a_shopping := &AmericaShopping{}shopping = NewShoppingProxy(a_shopping)shopping.Buy(g2)
}/*输出结果:购买了一件韩国商品: 韩国化妆品对韩国购买的商品:韩国化妆品,加征100%关税购买了一件美国商品: 美国生鱼片对美国购买的商品:美国生鱼片,加征120%关税
*/
代码解释:

我们定义了抽象服务提供商 shopping,也定义了具体的服务提供商 koreaShopping 和 AmericaShopping 以及代理ShoppingProxy,他们都实现了Buy(good)方法,代理还额外增加了CheckIn(good Good)方法,用于海关安检。在业务逻辑层,定义了两种商品(韩国化妆品和美国生鱼片),实例化了具体的韩国服务提供商和美国服务提供商,并传入代理中,用于代理对他们进行管理。

代理模式的优点:
  1. 能够一定程度上实现业务逻辑和具体的服务提供商的解耦,协调服务调用者和服务提供商之间的关系
  2. 业务逻辑层可以面向接口编程,符合开闭原则,扩展起来比较方便
代理模式的缺点:
  1. 代理类比较复杂庞大,所有实现的逻辑都堆叠在代理类中,不方便维护。

总结

本文,我们一起学习了什么是代理模式以及为什么需要代理模式,通俗一点理解,代理就是能够对具体的服务对象进行统一管理,并且代替服务对象向我们提供服务,我们请求服务时,只需要向代理请求即可,无需直接向具体的服务对象请求服务,此外代理还可以增加一些其他功能为我们提供更强的服务。

写在最后

感谢大家的阅读,晴天将继续努力,分享更多有趣且实用的主题,如有错误和纰漏,欢迎留言给予指正。 更多文章敬请关注作者个人公众号 晴天码字。 我们下期不见不散,to be continued…

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LaTeX 数学公式常见问题及解决方案

本文汇总了博主在使用 LaTeX 写文档过程中遇到的所有数学公式常见问题及对应的 LaTeX 解决方案 持续更新... 目录 1. 连等式2. 公式重新开始编号2.1 图片/表格重新编号 1. 连等式 在数学公式推导过程中常常会遇到如 Figure 1 所示的连等式,一般需要保证等号或者不等…

英伟达AI布局的新动向:H200 GPU开启生成式AI的新纪元

英伟达Nvidia是全球领先的AI计算平台和GPU制造商,近年来一直在不断推出创新的AI产品和解决方案,为各行各业的AI应用提供强大的支持。 最近,英伟达在GTC 2023大会上发布了一款专为训练和部署生成式AI模型的图形处理单元(GPU&#…

无需公网IP、简单3步,直连远程NAS实现高速访问

面对NAS远程访问难题 蒲公英旁路组网盒子X1 一招搞定! 无需公网IP、无需设置原有路由 简单3步,即可实现异地组网 更有点对点直连(P2P)模式 不限流量、不限速 传输速率取决于实际网络带宽 贝锐蒲公英X1,无需改变原…

springboot项目中没有识别到yml文件解决办法

springboot项目中没有识别到yml文件解决办法 ![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传] 1、这个意思就是没有配置数据库的数据源路径。所以需要配置数据源,比如mysql的驱动和路径。检查是否在properties或者yml文件中是否已经配置好。…

Python 利用PIL由多张图片合成gif动画

Python 由多张图片合成gif动画 案例 import os figure_save_path "file_fig_test" import warnings warnings.filterwarnings("error") import numpy as np np.random.seed(0) import matplotlib.pyplot as plt from PIL import Image import timenum 1…

YOLO目标检测——烟雾检测数据集下载分享【含对应voc、coco和yolo三种格式标签】

实际项目应用:烟雾检测数据集可用于监控烟雾情况,实现火灾的早期预警。数据集说明:烟雾检测数据集,真实场景的高质量图片数据,数据场景丰富,含烟雾1个类别标签说明:使用lableimg标注软件标注&am…

c语言:模拟实现qsort函数

qsort函数的功能: qsort相较于冒泡排序法,不仅效率更快,而且能够比较不同类型的元素,如:浮点数,结构体等等。这里我们来模拟下qsort是如何实现这一功能的,方便我们对指针数组有一个更深层次的理…

mmdet 3.x 打印各类指标

和mmdet2.x中的修改地方不一样,在mmdet/evaluation/metrics/coco_metric.py中第72行将classwise设为True就可以打印各类指标了 但是在test的时候一直都是什么指标都不打印,不管是上面总的指标还是下面的各类指标,暂时不知道怎么处理 找到原因…

“贾维斯”落地国内头部手机厂商? 这个AI助手真顶顶顶顶顶!

一个新的“贾维斯”即将落地国内头部手机厂商? 大家好,我是卖萌酱。 就在近日,2023 OPPO开发者大会正式官宣发布自主训练的大模型AndesGPT全新小布智能助手,算是正式预告国内头部一线手机厂商已经几乎全部完成大模型终端的布局。…

Egress Gateway

目录 文章目录 目录本节实战Egress Gateway访问外部服务1.Envoy 转发流量到外部服务2.控制对外部服务的访问3.直接访问外部服务总结 Egress 出口网关1.用 Egress gateway 发起 HTTP 请求2.用 Egress gateway 发起 HTTPS 请求 关于我最后 本节实战 实战名称🚩 实战&…

经典ctf ping题目详解 青少年CTF-WEB-PingMe02

题目环境: 根据题目名称可知 这是一道CTF-WEB方向常考的知识点:ping地址 随便ping一个地址查看接受的数据包?ip0.0.0.0 有回显数据,尝试列出目录文件 堆叠命令使用’;作为命令之间的连接符,当上一个命令完成后,继续执…

Buildroot 添加 Qt 支持

Buildroot 添加 Qt 支持 lqonlylove 于 2022-12-03 13:37:34 发布 阅读量2.8k 收藏 12 点赞数3 分类专栏: 根文件系统制作 文章标签: qt buildroot 版权 ​编辑根文件系统制作专栏收录该内容 2 篇文章0 订阅 订阅专栏 一、制作根文件系统 Buildroot 制作根文件系统_l…