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

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

代理模式-本文目录

什么是代理模式

我们先来看看 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 main

import "fmt"

// 代理模式
// 定义需要购买的商品的结构
type Good struct {
	Name     string
	Producer 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 ShoppingProxy
	shopping = 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…

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

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

相关文章

异步任务线程池——最优雅的方式创建异步任务

对于刚刚从校园出来的菜鸡选手很容易写出自以为没问题的屎山代码,可是当上线后就会立即暴露出问题,这说到底还是基础不够扎实!只会背八股文,却不理解,面试头头是道,一旦落地就啥也不是。此处,抛…

搭建mysql主从错误集合

1 mysqld --verbose --help --log-bin-index/tmp/tmp.Frnt2oibYI mysqld: Cant read dir of /etc/mysql/conf.d/ my.cnf是在/etc/mysql/conf.d/文件夹下,所以挂载的时候不要写/etc/mysql 2 COLLATION utf8_unicode_ci is not valid for CHARACTER SET latin1 配…

Linux系统编程学习 NO.9——git、gdb

前言 本篇文章简单介绍了Linux操作系统中两个实用的开发工具git版本控制器和gdb调试器。 git 什么是git? git是一款开源的分布式版本控制软件。它不仅具有网络功能,还是服务端与客户端一体的软件。它可以高效的处理程序项目中的版本管理。它是Linux内…

Flink(七)【输出算子(Sink)】

前言 今天是我写博客的第 200 篇,恍惚间两年过去了,现在已经是大三的学长了。仍然记得两年前第一次写博客的时候,当时学的应该是 Java 语言,菜的一批,写了就删,怕被人看到丢脸。当时就想着自己一年之后&…

WeTab--颜值与实力并存的浏览器插件

一.前言 现在的浏览器花花绿绿,有大量的广告与信息,令人目不暇接。有没有一款好用的浏览器插件可以解决这个问题呢?我愿称WeTab为版本答案。 WeTab的界面: 干净又整洁。最最关键的是还有智能AI供你服务。 这个WeTabAI就像chatgp…

Sam Altman 被罢免细节曝光,投资 100+ 公司或成「话柄」?

2022 年 11 月,ChatGPT 发布掀起 AI 狂潮。时隔 1 年,2023 年 11 月,ChatGPT 之父、Sam Altman 的一项人事巨变,再次掀起了一场 AI 界的风暴,只是这次并不是技术革命,而是 OpenAI 巨头换帅——Sam Altman 被…

高斯积分-Gaussian Quadrature

https://mathworld.wolfram.com/GaussianQuadrature.html

目标检测—YOLO系列(二 ) 全面解读复现YOLOv1 PyTorch

精读论文 前言 从这篇开始,我们将进入YOLO的学习。YOLO是目前比较流行的目标检测算法,速度快且结构简单,其他的目标检测算法如RCNN系列,以后有时间的话再介绍。 本文主要介绍的是YOLOV1,这是由以Joseph Redmon为首的…

Postman接收列表、数组参数@RequestParam List<String> ids

示例如下: 接口定义如下: GetMapping(value "/queryNewMoviePath")public List<Map<String, Object>> queryNewMoviePath(RequestParam List<String> ids ) {return service.queryNewMoviePath(ids);}postman中测试如下&#xff1a; http://loc…

linux、windows 查看java等进程占用资源情况

linux查看进程占用资源情况&#xff1a; top -o %MEM -b -n 1 | grep java | awk {print "PID: "$1" \t 虚拟内存: "$5" \t 物理内存: "$6" \t 共享内存: "$7" \t CPU使用率: "$9"% \t 内存使用率: "$10"%&…

剑指JUC原理-20.并发编程实践

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码&#x1f525;如果感觉博主的文章还不错的话&#xff0c;请&#x1f44d;三连支持&…

C/C++ 运用WMI接口查询系统信息

Windows Management Instrumentation&#xff08;WMI&#xff09;是一种用于管理和监视Windows操作系统的框架。它为开发人员、系统管理员和自动化工具提供了一种标准的接口&#xff0c;通过这个接口&#xff0c;可以获取有关计算机系统硬件、操作系统和应用程序的信息&#xf…

Maven依赖管理项目构建工具(保姆级教学---下篇)

对于Maven依赖管理项目构建工具的介绍&#xff0c;我们将其分为上篇和下篇。如果您对文章感兴趣&#xff0c;您可以在此链接中找到上篇详细内容&#xff1a; Maven依赖管理项目构建工具&#xff08;保姆级教学上篇&#xff09;-CSDN博客 一、Maven依赖传递和依赖冲突 1. …

SQL 文本函数

前言 SQL文本函数是SQL语言中非常有用的一类函数&#xff0c;它们用于处理和操作字符串数据。在实际应用中&#xff0c;我们经常需要对数据库中的文本数据进行各种操作&#xff0c;比如提取子串、替换子串、拼接字符串等等。而SQL文本函数可以帮助我们轻松地完成这些任务&#…

Egress Gateway

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

Scrum框架中的Sprint

上图就是sprint里要做的事。Sprint是scrum框架的核心&#xff0c;是所有的想法、主意转换为价值的地方。所有实现产品目标的必要工作都在sprint里完成&#xff0c;这些工作主要包括Sprint 计划&#xff08;Sprint planning&#xff09;、每日站会&#xff08;Daily Scrum&#…

JavaEE——简单认识HTML

文章目录 一、简单解释 HTML二、认识 HTML 的结构三、了解HTML中的相关标签1.注释标签2.标题标签3.段落标签 p4. 换行标签 br5.格式化标签6.图片标签解释 src解释 alt解释其他有关 img 标签的属性 7.超链接标签 a8.表格标签9.列表标签10.input 标签11. select 下拉菜单以及 div…

大数据研发工程师课前环境搭建

大数据研发工程师课前环境搭建 第一章 VMware Workstation 安装 在Windows的合适的目录来进行安装&#xff0c;如下图 1.1 双击打开 1.2 下一步&#xff0c;接受协议 1.3 选择安装位置 1.4 用户体验设置 1.5 快捷方式 已经准备好安装&#xff0c;点击安装 1.6 安装中 1.7 安装…

现在的各类解释非常混乱,到底什么是智慧城市?

智慧城市&#xff0c;简单来说&#xff0c;就是运用先进的信息和通信技术&#xff0c;让城市管理更加智能、高效&#xff0c;让市民的生活更加便捷、舒适。 在我们日常生活中&#xff0c;智慧城市带来的改变无处不在。 想象一下&#xff0c;当你早上醒来&#xff0c;你的手机已…

栈和队列的初始化,插入,删除,销毁。

目录 题外话 顺序表和链表优缺点以及特点 一.栈的特点 二. 栈的操作 2.1初始化 2.2 栈的销毁 2.3 栈的插入 2.3 输出top 2.4 栈的删除 2.5 输出栈 题外话 顺序表和链表优缺点以及特点 特点&#xff1a;顺序表&#xff0c;逻辑地址物理地址。可以任意访问&#xff0c…