代理模式通过代理对象控制对真实对象的访问,适用于权限校验、延迟初始化等场景。1. 定义Service接口,RealService实现具体逻辑,proxyService持有RealService引用并在Request中检查userRole权限,非admin则拒绝访问;2. 示例中NewProxyService创建不同角色代理,admin可访问并触发日志记录,guest直接被拒绝;3. 常见应用包括权限验证、延迟加载、日志监控、缓存及远程代理,提升系统灵活性与安全性。

在go语言中,代理模式是一种结构型设计模式,它通过引入一个代理对象来控制对真实对象的访问。这种模式常用于延迟初始化、权限校验、日志记录或网络请求代理等场景。下面介绍如何使用代理模式实现访问控制。
1. 代理模式的基本结构
代理模式通常包含三个核心部分:
- 接口(Interface):定义真实对象和代理对象共同实现的行为。
- 真实对象(Real Subject):实现具体业务逻辑。
- 代理对象(Proxy):持有真实对象的引用,在调用前后加入控制逻辑。
例如,我们想控制对某个服务的访问,可以先定义一个通用接口:
type Service interface { Request() string }
真实的服务实现:
立即学习“go语言免费学习笔记(深入)”;
type RealService struct{} func (r *RealService) Request() string { return "RealService: 处理请求" }
代理服务,在访问前进行权限检查:
type ProxyService struct { realService *RealService userRole string } func (p *ProxyService) Request() string { if p.userRole != "admin" { return "拒绝访问:权限不足" } // 延迟初始化真实对象 if p.realService == nil { p.realService = &RealService{} } return p.realService.Request() }
2. 使用代理控制访问示例
下面是一个完整示例,展示如何通过代理限制非管理员用户的访问:
package main import "fmt" // Service 接口统一访问方式 type Service interface { Request() string } // RealService 真实业务逻辑 type RealService struct{} func (r *RealService) Request() string { return "RealService: 处理请求" } // ProxyService 代理,控制访问 type ProxyService struct { realService *RealService userRole string } func (p *ProxyService) Request() string { if p.userRole != "admin" { return "拒绝访问:权限不足" } if p.realService == nil { p.realService = &RealService{} } fmt.Println("Proxy: 记录日志 - 用户开始请求") result := p.realService.Request() fmt.Println("Proxy: 记录日志 - 请求完成") return result } // NewProxyService 工厂函数创建代理 func NewProxyService(role string) Service { return &ProxyService{userRole: role} } func main() { adminProxy := NewProxyService("admin") guestProxy := NewProxyService("guest") fmt.Println(adminProxy.Request()) // 输出: // Proxy: 记录日志 - 用户开始请求 // RealService: 处理请求 // Proxy: 记录日志 - 请求完成 fmt.Println(guestProxy.Request()) // 输出: // 拒绝访问:权限不足 }
3. 常见应用场景
代理模式在Go中可用于多种访问控制场景:
- 权限验证:如上面例子,在调用前检查用户角色。
- 延迟加载:真实对象较大时,仅在需要时才创建。
- 日志与监控:在方法调用前后插入日志或性能统计。
- 缓存代理:代理可缓存结果,减少对真实对象的调用。
- 远程代理:本地代理代表远程服务,隐藏网络通信细节。
代理模式让访问控制变得灵活,无需修改真实对象代码即可增强行为。
基本上就这些。


