Skip to content
← 返回设计模式列表
设计意图与对象责任

代理 ​

通过代理控制对目标的访问。

结构型

说明 ​

权限校验、延迟加载等发生在真实对象之前或之后;代理保持相同接口。

分析 ​

Guard 与 Remote 都实现 Data,因此客户端无需因访问控制而更改调用代码。代理先检查 Allowed,只有允许时才转发给真实对象。

Guard 保持 Data.Get 接口,Allowed=false 时直接返回 denied,根本不会调用 Remote.Get。示例用字符串表达拒绝,真实接口应避免把错误字符串与合法业务数据混淆。代理成立的前提是访问必须经过它;若调用方还能直接获取 Remote,权限控制就不是完整边界。

查看图表代码

适用前提与边界 ​

同样的结构可用于缓存或延迟创建,但涉及权限时必须确保不存在绕过代理的直接入口。 只有接口适配或独立变化确实存在时,才增加额外包装层。

示例输入与调用 ​

go
var data Data = Guard{Target: Remote{}, Allowed: false}
	fmt.Println(data.Get())

运行输出 ​

text
denied

完整 Go 示例 ​

go
package main

import "fmt"

type Data interface{ Get() string }
type Remote struct{}

func (Remote) Get() string {
	return "secret"
}

type Guard struct {
	Target  Data
	Allowed bool
}

func (g Guard) Get() string {
	if !g.Allowed {
		return "denied"
	}
	return g.Target.Get()
}

func main() {
	var data Data = Guard{Target: Remote{}, Allowed: false}
	fmt.Println(data.Get())
}

继续阅读