Go设计模式(11)-代理模式 go 代理
yuyutoo 2024-10-13 09:10 8 浏览 0 评论
前面通过5篇文章讲解了创建型模式,创建型模式主要解决对象的创建问题,封装复杂的创建过程,解耦对象的创建代码和使用代码。
- Go设计模式(6)-单例模式:用于创建全局唯一对象
- Go设计模式(7)-工厂模式:用于根据参数,创建不同但是相关类型的对象
- Go设计模式(8)-抽象工厂:用于创建对象时,减少工厂类个数,增加可维护性
- Go设计模式(9)-建造者模式:用于创建复杂对象
- Go设计模式(10)-原型模式:用于创建成本较大的对象
从本篇文章开始讲解结构型模式,结构型模式主要总结了一些类或对象组合在一起的经典结构,这些经典的结构可以解决特定应用场景的问题。
代理模式能够在不改变原始类(或叫被代理类)代码的情况下,通过引入代理类来给原始类附加功能。一般代理类和被代理类有同一个父类。
本文UML类图链接为:https://www.processon.com/view/link/609b39d6f346fb5a37705da6
本文代码链接为:https://github.com/shidawuhen/asap/blob/master/controller/design/11proxy.go
1.定义
1.1代理模式
代理模式:为其他对象提供一种代理以控制对这个对象的访问。
UML类图:
1.2分析
看UML类图,可以看出代理类Proxy和被代理类RealSubject实现了相同接口Subject,代理类包含被代理类的引用。代理模式实现了在被代理类外面套了一层壳。虽然整体的设计和思想都很简单,但效果却很明显。首先在请求RealSubject的时候,必须经过Proxy,这样一些前置或者后置通用操作都可以放在Proxy中,扩展性和通用性都会加强。其次,因为Proxy和RealSubject各自实现了一部分功能,会使RealSubject更加关注自己的业务逻辑,起到很好的隔离效果。
2. 使用场景
使用代理模式的场景有以下这些:
1)业务系统的非功能性需求开发:如监控、统计、鉴权、限流、事务、幂等、日志等,这些和业务没有关系,所以可以放到Proxy中,RealSubject只关注功能性需求。以前写过一篇文章如何高效对接第三方支付,公司对接了大量的第三方支付公司(PayU、PayTM、WX),这些公司发起支付的流程是一样的,核心是获取token,但是还要做很多琐碎、通用的工作,如校验签名、初始化订单数据、参数检查、记录日志等。这些琐碎功能如果让每一个支付类自己处理,不但是重复开发,而且后期修改时不易维护,这时候就很适合用代理模式。
2)框架设计,如RPC的实现。调用RPC客户端,客户端会自动调用RPC服务端,客户端也是一个代理,做了大量操作让开发者可以不关心是如何成功调用到服务端的,只需要关心逻辑实现即可。
3.代码实现
这里简单实现一下支付网关发起支付功能是如何使用代理模式的。
package main
import (
"fmt"
)
/**
* @Description: 支付接口,只包含发起支付功能
*/
type PaymentService interface {
pay(order string) string
}
/**
* @Description: 微信支付类
*/
type WXPay struct {
}
/**
* @Description: 微信支付类,从微信获取支付token
* @receiver w
* @param order
* @return string
*/
func (w *WXPay) pay(order string) string {
return "从微信获取支付token"
}
/**
* @Description: 阿里支付类
*/
type AliPay struct {
}
/**
* @Description: 阿里支付类,从阿里获取支付token
* @receiver a
* @param order
* @return string
*/
func (a *AliPay) pay(order string) string {
return "从阿里获取支付token"
}
/**
* @Description: 支付代理类
*/
type PaymentProxy struct {
realPay PaymentService
}
/**
* @Description: 做校验签名、初始化订单数据、参数检查、记录日志、组装这种通用性操作,调用真正支付类获取token
* @receiver p
* @param order
* @return string
*/
func (p *PaymentProxy) pay(order string) string {
fmt.Println("处理" + order)
fmt.Println("1校验签名")
fmt.Println("2格式化订单数据")
fmt.Println("3参数检查")
fmt.Println("4记录请求日志")
token := p.realPay.pay(order)
return "http://组装" + token + "然后跳转到第三方支付"
}
func main() {
proxy := &PaymentProxy{
realPay: &AliPay{},
}
url := proxy.pay("阿里订单")
fmt.Println(url)
}
输出为:
? myproject go run main.go
处理阿里订单
1校验签名
2格式化订单数据
3参数检查
4记录请求日志
http://组装从阿里获取支付token然后跳转到第三方支付
代码比较简单,但效果还是很好的,大家可以思考一下,如果再使用上Go设计模式(7)-工厂模式,是不是就全自动化了,今后接入新的第三方支付,只需要开发新的支付类,框架上几乎不需要修改,研发和测试的成本会降低很多。这也解释了设计模式的妙用。
总结
代理模式简单实用,使用得当能让系统可扩展性增强。它能帮助开发者实现具体业务和通用逻辑的分离,是开发者只需关注具体业务,满足开放-封闭、里氏替换、依赖倒转等原则。
最后
大家如果喜欢我的文章,可以关注我的公众号(程序员麻辣烫)
我的个人博客为:https://shidawuhen.github.io/
往期文章回顾:
招聘
- 字节跳动|今日头条广州服务端研发工程师内推
- 字节跳动|抖音电商急招上海前端开发工程
- 字节跳动|抖音电商上海资深服务端开发工程师-交易
- 字节跳动|抖音电商武汉服务端(高级)开发工程师
- 字节跳动|飞书大客户产品经理内推咯
- 字节跳动|抖音电商服务端技术岗位虚位以待
- 字节跳动招聘专题
设计模式
- Go设计模式(10)-原型模式
- Go设计模式(9)-建造者模式
- Go设计模式(8)-抽象工厂
- Go设计模式(7)-工厂模式
- Go设计模式(6)-单例模式
- Go设计模式(5)-类图符号表示法
- Go设计模式(4)-代码编写优化
- Go设计模式(4)-代码编写
- Go设计模式(3)-设计原则
- Go设计模式(2)-面向对象分析与设计
- Go设计模式(1)-语法
语言
- 一文搞懂pprof
- Go工具之generate
- Go单例实现方案
- Go通道实现原理
- Go定时器实现原理
- Beego框架使用
- Golang源码BUG追查
- Gin框架简洁版
- Gin源码剖析
架构
- 支付接入常规问题
- 限流实现2
- 秒杀系统
- 分布式系统与一致性协议
- 微服务之服务框架和注册中心
- 浅谈微服务
- 限流实现1
- CDN请求过程详解
- 常用缓存技巧
- 如何高效对接第三方支付
- 算法总结
存储
- MySQL开发规范
- Redis实现分布式锁
- 事务原子性、一致性、持久性的实现原理
- InnoDB锁与事务简析
网络
- HTTP2.0基础教程
- HTTPS配置实战
- HTTPS连接过程
- TCP性能优化
工具
- GoLand实用技巧
- 根据mysql表自动生成go struct
- Markdown编辑器推荐-typora
读书笔记
- 《毛选》推荐
- 原则
- 资治通鉴
- 敏捷革命
- 如何锻炼自己的记忆力
- 简单的逻辑学-读后感
- 热风-读后感
- 论语-读后感
- 孙子兵法-读后感
思考
- 为动员一切力量争取胜利而斗争
- 反对自由主义
- 实践论
- 评价自己的标准
- 服务端团队假期值班方案
- 项目流程管理
- 对项目管理的一些看法
- 对产品经理的一些思考
- 关于程序员职业发展的思考
- 关于代码review的思考
相关推荐
- ETCD 故障恢复(etc常见故障)
-
概述Kubernetes集群外部ETCD节点故障,导致kube-apiserver无法启动。...
- 在Ubuntu 16.04 LTS服务器上安装FreeRADIUS和Daloradius的方法
-
FreeRADIUS为AAARadiusLinux下开源解决方案,DaloRadius为图形化web管理工具。...
- 如何排查服务器被黑客入侵的迹象(黑客 抓取服务器数据)
-
---排查服务器是否被黑客入侵需要系统性地检查多个关键点,以下是一份详细的排查指南,包含具体命令、工具和应对策略:---###**一、快速初步检查**####1.**检查异常登录记录**...
- 使用 Fail Ban 日志分析 SSH 攻击行为
-
通过分析`fail2ban`日志可以识别和应对SSH暴力破解等攻击行为。以下是详细的操作流程和关键分析方法:---###**一、Fail2ban日志位置**Fail2ban的日志路径因系统配置...
- 《5 个实用技巧,提升你的服务器安全性,避免被黑客盯上!》
-
服务器的安全性至关重要,特别是在如今网络攻击频繁的情况下。如果你的服务器存在漏洞,黑客可能会利用这些漏洞进行攻击,甚至窃取数据。今天我们就来聊聊5个实用技巧,帮助你提升服务器的安全性,让你的系统更...
- 聊聊Spring AI Alibaba的YuQueDocumentReader
-
序本文主要研究一下SpringAIAlibaba的YuQueDocumentReaderYuQueDocumentReader...
- Mac Docker环境,利用Canal实现MySQL同步ES
-
Canal的使用使用docker环境安装mysql、canal、elasticsearch,基于binlog利用canal实现mysql的数据同步到elasticsearch中,并在springboo...
- RustDesk:开源远程控制工具的技术架构与全场景部署实战
-
一、开源远程控制领域的革新者1.1行业痛点与解决方案...
- 长安汽车一代CS75Plus2020款安装高德地图7.5
-
不用破解原车机,一代CS75Plus2020款,安装车机版高德地图7.5,有红绿灯读秒!废话不多讲,安装步骤如下:一、在拨号状态输入:在电话拨号界面,输入:*#518200#*(进入安卓设置界面,...
- Zookeeper使用详解之常见操作篇(zookeeper ui)
-
一、Zookeeper的数据结构对于ZooKeeper而言,其存储结构类似于文件系统,也是一个树形目录服务,并通过Key-Value键值对的形式进行数据存储。其中,Key由斜线间隔的路径元素构成。对...
- zk源码—4.会话的实现原理一(会话层的基本功能是什么)
-
大纲1.创建会话...
- Zookeeper 可观测性最佳实践(zookeeper能够确保)
-
Zookeeper介绍ZooKeeper是一个开源的分布式协调服务,用于管理和协调分布式系统中的节点。它提供了一种高效、可靠的方式来解决分布式系统中的常见问题,如数据同步、配置管理、命名服务和集群...
- 服务器密码错误被锁定怎么解决(服务器密码错几次锁)
-
#服务器密码错误被锁定解决方案当服务器因多次密码错误导致账户被锁定时,可以按照以下步骤进行排查和解决:##一、确认锁定状态###1.检查账户锁定状态(Linux)```bash#查看账户锁定...
- zk基础—4.zk实现分布式功能(分布式zk的使用)
-
大纲1.zk实现数据发布订阅...
- 《死神魂魄觉醒》卡死问题终极解决方案:从原理到实战的深度解析
-
在《死神魂魄觉醒》的斩魄刀交锋中,游戏卡死犹如突现的虚圈屏障,阻断玩家与尸魂界的连接。本文将从技术架构、解决方案、预防策略三个维度,深度剖析卡死问题的成因与应对之策,助力玩家突破次元壁障,畅享灵魂共鸣...
你 发表评论:
欢迎- 一周热门
-
-
前端面试:iframe 的优缺点? iframe有那些缺点
-
带斜线的表头制作好了,如何填充内容?这几种方法你更喜欢哪个?
-
漫学笔记之PHP.ini常用的配置信息
-
其实模版网站在开发工作中很重要,推荐几个参考站给大家
-
推荐7个模板代码和其他游戏源码下载的网址
-
[干货] JAVA - JVM - 2 内存两分 [干货]+java+-+jvm+-+2+内存两分吗
-
正在学习使用python搭建自动化测试框架?这个系统包你可能会用到
-
织梦(Dedecms)建站教程 织梦建站详细步骤
-
【开源分享】2024PHP在线客服系统源码(搭建教程+终身使用)
-
2024PHP在线客服系统源码+完全开源 带详细搭建教程
-
- 最近发表
-
- ETCD 故障恢复(etc常见故障)
- 在Ubuntu 16.04 LTS服务器上安装FreeRADIUS和Daloradius的方法
- 如何排查服务器被黑客入侵的迹象(黑客 抓取服务器数据)
- 使用 Fail Ban 日志分析 SSH 攻击行为
- 《5 个实用技巧,提升你的服务器安全性,避免被黑客盯上!》
- 聊聊Spring AI Alibaba的YuQueDocumentReader
- Mac Docker环境,利用Canal实现MySQL同步ES
- RustDesk:开源远程控制工具的技术架构与全场景部署实战
- 长安汽车一代CS75Plus2020款安装高德地图7.5
- Zookeeper使用详解之常见操作篇(zookeeper ui)
- 标签列表
-
- mybatis plus (70)
- scheduledtask (71)
- css滚动条 (60)
- java学生成绩管理系统 (59)
- 结构体数组 (69)
- databasemetadata (64)
- javastatic (68)
- jsp实用教程 (53)
- fontawesome (57)
- widget开发 (57)
- vb net教程 (62)
- hibernate 教程 (63)
- case语句 (57)
- svn连接 (74)
- directoryindex (69)
- session timeout (58)
- textbox换行 (67)
- extension_dir (64)
- linearlayout (58)
- vba高级教程 (75)
- iframe用法 (58)
- sqlparameter (59)
- trim函数 (59)
- flex布局 (63)
- contextloaderlistener (56)