百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程网 > 正文

Go设计模式(11)-代理模式 go 代理

yuyutoo 2024-10-13 09:10 2 浏览 0 评论

前面通过5篇文章讲解了创建型模式,创建型模式主要解决对象的创建问题,封装复杂的创建过程,解耦对象的创建代码和使用代码。

  1. Go设计模式(6)-单例模式:用于创建全局唯一对象
  2. Go设计模式(7)-工厂模式:用于根据参数,创建不同但是相关类型的对象
  3. Go设计模式(8)-抽象工厂:用于创建对象时,减少工厂类个数,增加可维护性
  4. Go设计模式(9)-建造者模式:用于创建复杂对象
  5. 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/

往期文章回顾:

招聘

  1. 字节跳动|今日头条广州服务端研发工程师内推
  2. 字节跳动|抖音电商急招上海前端开发工程
  3. 字节跳动|抖音电商上海资深服务端开发工程师-交易
  4. 字节跳动|抖音电商武汉服务端(高级)开发工程师
  5. 字节跳动|飞书大客户产品经理内推咯
  6. 字节跳动|抖音电商服务端技术岗位虚位以待
  7. 字节跳动招聘专题

设计模式

  1. Go设计模式(10)-原型模式
  2. Go设计模式(9)-建造者模式
  3. Go设计模式(8)-抽象工厂
  4. Go设计模式(7)-工厂模式
  5. Go设计模式(6)-单例模式
  6. Go设计模式(5)-类图符号表示法
  7. Go设计模式(4)-代码编写优化
  8. Go设计模式(4)-代码编写
  9. Go设计模式(3)-设计原则
  10. Go设计模式(2)-面向对象分析与设计
  11. Go设计模式(1)-语法

语言

  1. 一文搞懂pprof
  2. Go工具之generate
  3. Go单例实现方案
  4. Go通道实现原理
  5. Go定时器实现原理
  6. Beego框架使用
  7. Golang源码BUG追查
  8. Gin框架简洁版
  9. Gin源码剖析

架构

  1. 支付接入常规问题
  2. 限流实现2
  3. 秒杀系统
  4. 分布式系统与一致性协议
  5. 微服务之服务框架和注册中心
  6. 浅谈微服务
  7. 限流实现1
  8. CDN请求过程详解
  9. 常用缓存技巧
  10. 如何高效对接第三方支付
  11. 算法总结

存储

  1. MySQL开发规范
  2. Redis实现分布式锁
  3. 事务原子性、一致性、持久性的实现原理
  4. InnoDB锁与事务简析

网络

  1. HTTP2.0基础教程
  2. HTTPS配置实战
  3. HTTPS连接过程
  4. TCP性能优化

工具

  1. GoLand实用技巧
  2. 根据mysql表自动生成go struct
  3. Markdown编辑器推荐-typora

读书笔记

  1. 《毛选》推荐
  2. 原则
  3. 资治通鉴
  4. 敏捷革命
  5. 如何锻炼自己的记忆力
  6. 简单的逻辑学-读后感
  7. 热风-读后感
  8. 论语-读后感
  9. 孙子兵法-读后感

思考

  1. 为动员一切力量争取胜利而斗争
  2. 反对自由主义
  3. 实践论
  4. 评价自己的标准
  5. 服务端团队假期值班方案
  6. 项目流程管理
  7. 对项目管理的一些看法
  8. 对产品经理的一些思考
  9. 关于程序员职业发展的思考
  10. 关于代码review的思考

相关推荐

jQuery VS AngularJS 你更钟爱哪个?

在这一次的Web开发教程中,我会尽力解答有关于jQuery和AngularJS的两个非常常见的问题,即jQuery和AngularJS之间的区别是什么?也就是说jQueryVSAngularJS?...

Jquery实时校验,指定长度的「负小数」,小数位未满末尾补0

在可以输入【负小数】的输入框获取到焦点时,移除千位分隔符,在输入数据时,实时校验输入内容是否正确,失去焦点后,添加千位分隔符格式化数字。同时小数位未满时末尾补0。HTML代码...

如何在pbootCMS前台调用自定义表单?pbootCMS自定义调用代码示例

要在pbootCMS前台调用自定义表单,您需要在后台创建表单并为其添加字段,然后在前台模板文件中添加相关代码,如提交按钮和表单验证代码。您还可以自定义表单数据的存储位置、添加文件上传字段、日期选择器、...

编程技巧:Jquery实时验证,指定长度的「负小数」

为了保障【负小数】的正确性,做成了通过Jquery,在用户端,实时验证指定长度的【负小数】的方法。HTML代码<inputtype="text"class="forc...

一篇文章带你用jquery mobile设计颜色拾取器

【一、项目背景】现实生活中,我们经常会遇到配色的问题,这个时候去百度一下RGB表。而RGB表只提供相对于的颜色的RGB值而没有可以验证的模块。我们可以通过jquerymobile去设计颜色的拾取器...

编程技巧:Jquery实时验证,指定长度的「正小数」

为了保障【正小数】的正确性,做成了通过Jquery,在用户端,实时验证指定长度的【正小数】的方法。HTML做成方法<inputtype="text"class="fo...

jquery.validate检查数组全部验证

问题:html中有多个name[],每个参数都要进行验证是否为空,这个时候直接用required:true话,不能全部验证,只要这个数组中有一个有值就可以通过的。解决方法使用addmethod...

Vue进阶(幺叁肆):npm查看包版本信息

第一种方式npmviewjqueryversions这种方式可以查看npm服务器上所有的...

layui中使用lay-verify进行条件校验

一、layui的校验很简单,主要有以下步骤:1.在form表单内加上class="layui-form"2.在提交按钮上加上lay-submit3.在想要校验的标签,加上lay-...

jQuery是什么?如何使用? jquery是什么功能组件

jQuery于2006年1月由JohnResig在BarCampNYC首次发布。它目前由TimmyWilson领导,并由一组开发人员维护。jQuery是一个JavaScript库,它简化了客户...

django框架的表单form的理解和用法-9

表单呈现...

jquery对上传文件的检测判断 jquery实现文件上传

总体思路:在前端使用jquery对上传文件做部分初步的判断,验证通过的文件利用ajaxFileUpload上传到服务器端,并将文件的存储路径保存到数据库。<asp:FileUploadI...

Nodejs之MEAN栈开发(四)-- form验证及图片上传

这一节增加推荐图书的提交和删除功能,来学习node的form提交以及node的图片上传功能。开始之前需要源码同学可以先在git上fork:https://github.com/stoneniqiu/R...

大数据开发基础之JAVA jquery 大数据java实战

上一篇我们讲解了JAVAscript的基础知识、特点及基本语法以及组成及基本用途,本期就给大家带来了JAVAweb的第二个知识点jquery,大数据开发基础之JAVAjquery,这是本篇文章的主要...

推荐四个开源的jQuery可视化表单设计器

jquery开源在线表单拖拉设计器formBuilder(推荐)jQueryformBuilder是一个开源的WEB在线html表单设计器,开发人员可以通过拖拉实现一个可视化的表单。支持表单常用控件...

取消回复欢迎 发表评论: