代理模式通过接口抽象、方法委托与权限校验间接控制对象行为,核心是让代理充当“守门人”:Go用接口+指针接收器实现静态鉴权;JavaScript用Proxy原生拦截属性读写;Java用动态代理+InvocationHandler统一拦截方法调用。

代理模式在实战中不直接拦截变量访问,而是通过接口抽象 + 方法委托 + 权限校验,间接控制对对象行为的调用。Go、Java、JavaScript 等语言实现方式差异明显,核心逻辑一致:**不让客户端直连真实对象,而经由代理做“守门人”**。
Go 语言:接口 + 结构体代理(无反射,轻量可控)
Go 没有运行时属性拦截能力,但可通过统一接口和指针接收器实现在方法调用前强制鉴权:
- 定义业务接口(如 UserService),包含 DeleteUser、UpdateProfile 等方法
- 真实实现 RealUserService 只专注数据操作,不处理权限
- 代理结构体 UserServiceProxy 持有 RealUserService 实例和 userRole string 字段
- 重写 DeleteUser 方法:先判断 userRole == "admin",否则返回 ErrPermissionDenied,不调用真实方法
- 所有方法必须使用指针接收器(func (p *UserServiceProxy) DeleteUser(...)),否则接口实现无效
JavaScript:Proxy 构造函数原生支持属性级拦截
JS 的 Proxy 可真正拦截读写操作,适合细粒度变量访问控制:
- 目标对象如 { name: "Alice", password: "123" }
- Handler 中定义 get 拦截:当访问 password 时,检查当前用户是否为管理员,否则返回 undefined 或抛错
- 定义 set 拦截:限制敏感字段(如 isAdmin)只能由系统初始化,禁止运行时修改
- 还可结合 has 和 ownKeys 隐藏私有属性,让 Object.keys() 不暴露受控字段
Java:动态代理面向接口,方法级权限可配置化
Java 动态代理不操作字段,而是对 InvocationHandler 统一拦截方法调用:
- 定义服务接口 DocumentService,含 read()、delete()、publish()
- 真实实现类 RealDocumentService 仅执行业务逻辑
- 自定义 PermissionInvocationHandler,内部维护 Map<Method, String> methodRoles 映射表
- 在 invoke() 中获取被调方法,查表得所需角色(如 delete → "ADMIN"),再比对当前用户角色
- 支持注解驱动:用 @RequireRole("ADMIN") 标记方法,运行时自动提取并校验
关键设计提醒
无论哪种语言,实战中需注意几个易忽略点:
- 代理对象与真实对象必须共用同一接口或父类,这是多态调用的前提
- 权限判断应放在方法入口,失败立即返回,避免资源浪费(如已打开文件句柄再拒绝)
- 不要在代理里硬编码权限规则;推荐外置配置(如 YAML 规则文件)或接入 RBAC 服务
- 日志、审计等横切逻辑可与权限代理解耦,用链式代理(AuthProxy → LogProxy → Real)组合复用
- 性能敏感场景慎用反射(如 Java 动态代理、Go 的通用 SecureProxy),优先选静态代理+编译期检查

















