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

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

yuyutoo 2024-10-13 09:10 12 浏览 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的思考

相关推荐

网络规划建设原来也可以这么简单!

废话少说,直接上干货。天气炎热,请各位看官老爷静心阅读。整体思路下图是关于网络建设的所有相关领域,接下来我为大家逐一讲解。网络分层...

网络规划设计师笔记-第 1 章 计算机网络原理

计算机网络原理1.1计算机网络概论(P1-10)...

别输在远见上,网工这样做职业规划,比啥都强

01职业中的规划,人生中的buff“职业规划“这个词,其实对很多年轻人,包括曾经年轻的我来说,都不屑一提。...

网络规划设计师学习中(个人自学笔记分享1),有一起学习的吗?

网络规划设计师,上午考试内容学习:第一章:计算机网络概述(上部分):如果你也在一起学习,那么我们来一起学习吧!坚持1年,争取明年一次性通过!...

在微服务中使用 ASP.NET Core 实现事件溯源和 CQRS

概述:事件溯源和命令查询责任分离(CQRS)已成为解决微服务设计的复杂性的强大架构模式。基本CQRS表示形式在本文中,我们将探讨ASP.NETCore如何使你能够将事件溯源和CQRS...

一个基于ASP.NET Core完全开源的CMS 解决方案

...

用 Nginx 部署 ASP.NET Core 应用程序

用Nginx部署ASP.NETCore应用程序步骤如下:在Linux中安装.NETCore运行时和Nginx:...

Asp.net Core启动流程讲解(一)(asp.net core 入门)

asp.netcore默认项目包括项目根目录级的Startup.cs、Program.cs、appsettings.json(appsettings.Development.json)launch...

十天学会ASP之第五天(十天学会asp教程)

学习目的:学会数据库的基本操作1(写入记录)数据库的基本操作无非是:查询记录,写入记录,删除记录,修改记录。今天我们先学习写入记录。先建立一个表单:<formname="form1"met...

ASP.NET Core 的 WebApplication 类

ASP.NETCore提供了3个主机类(Host)。这些类用于配置应用、管理生命周期和启动Web服务。...

ASP.NET Core中的键控依赖注入(.net依赖注入原理)

大家好,我是深山踏红叶,今天我们来聊一聊ASP.NETCore中的FromKeyedServices,它是在.Net8中引入的。这一特性允许通过键(如字符串或枚举)来注册和检索依赖注入(D...

Asp.net常用方法及request和response-a

asp.net教程asp.net常用方法:1、Request.UrlReferrer请求的来源,可以根据这个判断从百度搜的哪个关键词、防下载盗链、防图片盗链,可以伪造(比如迅雷)。(使用全局一般处理...

ASP.NET Core EFCore 属性配置与DbContext 详解

...

asp.net常考面试题(aspnet题库)

asp.net常考面试题一,列举ASP.Net页面之间传递值的几种方式?1,使用QueryString,如:......?id=1;response.Redirect()......2,使用Sessi...

在Windows系统搭建.NET Core环境并创建运行ASP.NET网站

微软于6月27日在红帽DevNation峰会上正式发布了.NETCore1.0、ASP.NET1.0和EntityFrameworkCore1.0,其将全部支持Windows、OSX和...

取消回复欢迎 发表评论: