代理模式通过统一接口让代理与真实对象实现相同行为,在调用前后插入鉴权、日志、缓存等逻辑,支持链式组合与HTTP中间件模拟,提升系统可控性与扩展性。

代理模式在 Golang 中常用于控制对目标对象的访问,比如添加鉴权、日志、缓存、限流或延迟加载等逻辑,而无需修改原始业务代码。核心思路是定义统一接口,让代理和真实对象都实现它,代理在调用真实对象前后插入自定义行为。
定义统一接口与真实服务
先设计一个基础接口(如 Service),再实现真实业务逻辑(RealService):
示例:
type Service interface {
Do() string
}
type RealService struct{}
func (r *RealService) Do() string {
return "执行核心业务"
}
实现代理结构体并封装行为
代理结构体持有真实对象指针,并在方法中加入控制逻辑:
立即学习“go语言免费学习笔记(深入)”;
- 可检查请求来源、Token 或权限
- 记录请求时间、参数和返回结果
- 决定是否放行、熔断或返回缓存
- 调用真实对象前/后插入处理
示例(带日志与简单鉴权):
type AuthServiceProxy struct {
service Service
token string
}
func NewAuthServiceProxy(s Service, t string) *AuthServiceProxy {
return &AuthServiceProxy{service: s, token: t}
}
func (a *AuthServiceProxy) Do() string {
if a.token != "valid-token" {
return "拒绝访问:无效凭证"
}
log.Println("→ 开始处理请求")
result := a.service.Do()
log.Println("← 请求完成")
return result
}
灵活组合多种代理(链式代理)
多个关注点可拆分为独立代理(如 AuthProxy、LogProxy、CacheProxy),通过嵌套实现职责分离:
- 每个代理只负责一件事,便于测试和复用
- 按需组装,例如:
newCacheProxy(newAuthProxy(newRealService())) - 注意调用顺序(如鉴权应在缓存之前,避免未授权访问缓存)
结合 HTTP 中间件模拟代理行为
在 Web 场景中,Golang 的 http.Handler 天然适合代理思想:
- 中间件函数接收
http.Handler并返回新http.Handler - 在
ServeHTTP中预处理请求、调用下一层、后处理响应 - 本质就是 HTTP 层的代理模式应用
典型写法:
func LoggingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Printf("收到请求: %s %s", r.Method, r.URL.Path)
next.ServeHTTP(w, r)
})
}
基本上就这些。代理模式不复杂但容易忽略边界——比如代理不应暴露真实对象内部细节,接口要足够抽象,代理自身也应可被代理。用好它,能让系统更可控、更易扩展。










