代理模式属于结构设计模式的一种,核心思想是通过一个代理对象来包装真实的目标对象,客户端不直接访问目标对象,而是和代理对象交互,代理对象可以在调用目标对象方法的前后添加额外的处理逻辑,比如权限校验、日志记录、性能统计等,同时还能控制客户端对目标对象的访问。

代理模式的核心角色
代理模式的实现通常包含三个核心角色:
- 抽象主题:定义真实主题和代理主题的共同接口,客户端面向该接口编程,不需要关心具体是真实对象还是代理对象。
- 真实主题:实现抽象主题接口,是真正执行业务逻辑的对象,也是代理对象所代理的目标。
- 代理主题:同样实现抽象主题接口,内部持有真实主题的引用,在调用真实主题方法前后可以添加自定义逻辑。
Golang静态代理实现示例
静态代理是最基础的代理模式实现方式,代理类的代码在编译期就已经确定,下面以用户服务为例,实现带权限校验的代理逻辑。
1. 定义抽象主题接口
首先定义用户服务的统一接口,包含查询用户信息的方法:
// UserService 抽象主题接口,定义用户服务的统一方法
type UserService interface {
GetUserInfo(userId int) string
}
2. 实现真实主题
真实主题实现上面的接口,完成实际的业务逻辑:
// RealUserService 真实主题,实现用户查询的实际逻辑
type RealUserService struct{}
// GetUserInfo 真实查询用户信息的方法
func (r *RealUserService) GetUserInfo(userId int) string {
// 模拟数据库查询逻辑
return "用户ID为" + string(rune(userId+'0')) + "的用户信息"
}
3. 实现代理主题
代理主题同样实现UserService接口,内部持有真实主题的实例,在调用真实方法前添加权限校验逻辑:
// UserProxyService 代理主题,包装真实用户服务,添加权限校验
type UserProxyService struct {
realService *RealUserService
// 模拟当前请求的权限标识
hasPermission bool
}
// NewUserProxyService 创建代理实例的构造函数
func NewUserProxyService(hasPermission bool) *UserProxyService {
return &UserProxyService{
realService: &RealUserService{},
hasPermission: hasPermission,
}
}
// GetUserInfo 代理方法,调用真实方法前先校验权限
func (p *UserProxyService) GetUserInfo(userId int) string {
// 调用真实方法前的额外逻辑:权限校验
if !p.hasPermission {
return "无权限访问该用户信息"
}
// 调用真实主题的方法
result := p.realService.GetUserInfo(userId)
// 调用真实方法后的额外逻辑:记录访问日志
// 这里模拟日志记录,实际开发中可对接日志组件
return result + ",访问日志记录完成"
}
4. 测试静态代理效果
编写测试代码验证静态代理的逻辑是否符合预期:
package main
import (
"fmt"
)
func main() {
// 创建有权限的代理实例
proxyWithPerm := NewUserProxyService(true)
fmt.Println("有权限访问结果:", proxyWithPerm.GetUserInfo(1))
// 创建无权限的代理实例
proxyNoPerm := NewUserProxyService(false)
fmt.Println("无权限访问结果:", proxyNoPerm.GetUserInfo(1))
}
运行上述代码,输出结果如下:
有权限访问结果: 用户ID为1的用户信息,访问日志记录完成 无权限访问结果: 无权限访问该用户信息
代理模式的使用场景与注意事项
代理模式在Golang开发中有很多适用场景:
- 需要控制外部对某个对象的访问权限时,可以用代理做权限校验。
- 需要在方法调用前后添加通用逻辑比如日志、统计、缓存时,用代理可以避免侵入真实业务逻辑。
- 真实对象创建成本较高时,可以用代理实现懒加载,等到真正需要使用时再创建真实对象。
需要注意静态代理的局限性:如果需要代理的接口方法较多,代理类需要逐个实现接口的所有方法,会导致代码冗余。如果需要更灵活的代理方式,可以考虑结合反射实现类似动态代理的逻辑,减少重复代码的编写。
Golang代理模式Proxy_Pattern设计模式修改时间:2026-06-13 07:15:30