Go中代理模式通过接口和组合实现,代理与真实对象实现同一接口,支持权限校验、懒加载、缓存及链式代理,调用方无感知。
在 Go 语言中,代理模式(Proxy Pattern)不依赖语言特性(如继承或多态),而是通过组合和接口来实现——核心是定义统一接口,让代理对象和真实对象都实现它,从而在不改变调用方代码的前提下,透明地控制对真实对象的访问、延迟初始化、权限校验、日志记录或缓存等操作。
定义统一接口,解耦调用方与实现
代理模式的前提是抽象出行为契约。例如,假设我们有一个资源加载器,需要控制对敏感文件的访问:
- 先定义 Loader 接口:func Load(path string) ([]byte, error)
- 真实对象 RealLoader 直接读取文件并返回内容
- 代理对象 AuthProxyLoader 持有 RealLoader 实例,并在调用 Load 前检查权限
实现带访问控制的代理
以下是一个权限校验代理示例:
type Loader interface {
Load(path string) ([]byte, error)
}
type RealLoader struct{}
func (r RealLoader) Load(path string) ([]byte, error) {
return os.ReadFile(path)
}
type AuthProxyLoader struct {
loader Loader
user string
}
func (p AuthProxyLoader) Load(path string) ([]byte, error) {
if !p.canAccess(path) {
return nil, fmt.Errorf("access denied for %s", path)
}
return p.loader.Load(path)
}
func (p AuthProxyLoader) canAccess(path string) bool {
// 简单策略:管理员可访问所有路径,普通用户仅限 /public/
return p.user == "admin" || strings.HasPrefix(path, "/public/")
}
使用时只需传入 AuthProxyLoader 实例,调用方完全感知不到代理逻辑。
支持懒加载与缓存的代理
代理还可用于优化性能。比如图片加载器,首次加载后缓存结果:
- 代理内部维护一个 map[string][]byte 缓存
- 每次 Load 先查缓存,命中则直接返回;未命中则委托给真实加载器,并存入缓存
- 注意并发安全:用 sync.RWMutex 保护读写
灵活组合多个代理(链式代理)
Go 的接口和组合天然适合构建代理链。例如:
- LoggingProxy:记录每次调用耗时与参数
- RateLimitProxy:限制单位时间调用次数
- CacheProxy:提供本地响应缓存
它们可按需嵌套:LoggingProxy{RateLimitProxy{CacheProxy{RealLoader{}}}},每个只关注自身职责,符合单一职责原则。

方无感知。






