0

0

如何使用Golang实现代理模式_Golang代理模式访问控制方法

P粉602998670

P粉602998670

发布时间:2026-01-08 11:55:36

|

390人浏览过

|

来源于php中文网

原创

Go中代理模式核心是interface+struct组合+方法委托,通过控制访问时机在调用前后插入逻辑,典型如鉴权、日志、限流等场景,需注意初始化、空指针及上下文传递。

如何使用golang实现代理模式_golang代理模式访问控制方法

代理模式在 Go 中的核心实现方式

Go 本身没有 class 和继承,所以不能照搬 Java 那套“接口 + 实现类 + 代理类”三层结构。真正的 Go 风格代理,靠的是 interface + struct 组合 + 方法委托,关键在于“控制访问时机”——不是拦截方法调用,而是在调用前后插入逻辑。

典型做法是定义一个服务接口(比如 DataService),让真实对象和代理对象都实现它;代理内部持有一个真实对象的指针,在自己的方法里决定是否、何时、如何调用真实对象的对应方法。

type DataService interface {
    Get(id int) (string, error)
    Save(data string) error
}

type RealDataService struct{}

func (r *RealDataService) Get(id int) (string, error) {
    return fmt.Sprintf("data-%d", id), nil
}

func (r *RealDataService) Save(data string) error {
    fmt.Println("saving:", data)
    return nil
}

type AuthProxy struct {
    ds DataService
    token string
}

func (p *AuthProxy) Get(id int) (string, error) {
    if !p.isValidToken() {
        return "", errors.New("unauthorized")
    }
    return p.ds.Get(id)
}

func (p *AuthProxy) Save(data string) error {
    if !p.isValidToken() {
        return errors.New("unauthorized")
    }
    return p.ds.Save(data)
}

func (p *AuthProxy) isValidToken() bool {
    return p.token == "valid-token"
}

用嵌入结构体简化代理逻辑

如果代理只是加一层校验或日志,不想重复写所有方法签名,可以用结构体嵌入(embedding)把真实对象“藏”进代理里,再选择性重写需要控制的方法。Go 会自动提升嵌入字段的方法,未重写的方法直接透传。

  • 嵌入后,AuthProxy 自动获得 GetSave 方法,但只有重写的那个才生效
  • 重写方法里用 p.RealDataService.Get(id) 显式调用原方法,避免无限递归
  • 注意:嵌入的是指针类型(*RealDataService),否则无法修改底层状态
type AuthProxy struct {
    *RealDataService // 嵌入
    token string
}

func (p *AuthProxy) Get(id int) (string, error) {
    if !p.isValidToken() {
        return "", errors.New("unauthorized")
    }
    return p.RealDataService.Get(id) // 显式调用
}

代理常用于访问控制的几个典型场景

代理模式在 Go 中最实在的用途不是“设计模式炫技”,而是解决具体访问控制问题:权限校验、限流、缓存、审计日志、延迟加载。重点不是“代理存在”,而是“在哪插逻辑”。

Cardify卡片工坊
Cardify卡片工坊

使用Markdown一键生成精美的小红书知识卡片

下载

立即学习go语言免费学习笔记(深入)”;

  • 鉴权失败立即返回:如上例,在 Get 开头检查 token,不满足就直接 return,真实对象根本不会被调用
  • 操作前/后钩子:比如 Save 方法里,可以在调用真实 Save 前记录日志,调用后更新统计计数器
  • 避免暴露真实对象细节:外部只依赖 DataService 接口,完全不知道背后是内存结构、数据库连接还是 HTTP 客户端
  • 测试友好:单元测试时可轻松用 mock 代理替换真实数据服务,无需改业务代码

容易踩的坑:空指针、循环引用、接口零值

代理对象本身是结构体,如果字段没初始化就调用方法,运行时 panic 是大概率事件。尤其要注意嵌入字段和依赖对象的初始化顺序。

  • AuthProxy{ds: nil} 然后调 Get() → panic: nil pointer dereference
  • 代理构造函数必须显式传入真实对象,不能依赖包级变量或全局单例(否则难以测试且隐藏依赖)
  • 如果代理要持有一些上下文(如 context.Context 或用户信息),别塞进结构体字段,应作为方法参数传入,否则并发下易出错
  • 接口类型变量的零值是 nil,判断代理是否持有真实对象要用 p.ds != nil,而不是 p.ds == nil 的反向逻辑来兜底

代理真正难的不是写法,而是想清楚“控制点”在哪——是每次调用都鉴权,还是只在敏感操作上?token 是从 HTTP header 解析,还是从 context.Value 取?这些决策比结构体怎么嵌入重要得多。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
golang如何定义变量
golang如何定义变量

golang定义变量的方法:1、声明变量并赋予初始值“var age int =值”;2、声明变量但不赋初始值“var age int”;3、使用短变量声明“age :=值”等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

211

2024.02.23

golang有哪些数据转换方法
golang有哪些数据转换方法

golang数据转换方法:1、类型转换操作符;2、类型断言;3、字符串和数字之间的转换;4、JSON序列化和反序列化;5、使用标准库进行数据转换;6、使用第三方库进行数据转换;7、自定义数据转换函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

247

2024.02.23

golang常用库有哪些
golang常用库有哪些

golang常用库有:1、标准库;2、字符串处理库;3、网络库;4、加密库;5、压缩库;6、xml和json解析库;7、日期和时间库;8、数据库操作库;9、文件操作库;10、图像处理库。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

356

2024.02.23

golang和python的区别是什么
golang和python的区别是什么

golang和python的区别是:1、golang是一种编译型语言,而python是一种解释型语言;2、golang天生支持并发编程,而python对并发与并行的支持相对较弱等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

214

2024.03.05

golang是免费的吗
golang是免费的吗

golang是免费的。golang是google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的开源编程语言,采用bsd开源协议。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

410

2024.05.21

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

490

2025.06.09

golang相关判断方法
golang相关判断方法

本专题整合了golang相关判断方法,想了解更详细的相关内容,请阅读下面的文章。

201

2025.06.10

golang数组使用方法
golang数组使用方法

本专题整合了golang数组用法,想了解更多的相关内容,请阅读专题下面的文章。

1499

2025.06.17

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

49

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 4.4万人学习

C# 教程
C# 教程

共94课时 | 11.4万人学习

Java 教程
Java 教程

共578课时 | 82.5万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号