代理模式 在不改变原始类(或叫被代理类)代码的情况下,通过引入代理类来给原始类附加功能,常用在业务系统中开发一些非功能性需求,比如:监控、统计、鉴权、限流、事务、幂等、 日志
逻辑结构

代码实现
代码路径:https://github.com/XBoom/DesignPatterns/tree/main/07_Proxy
-
需要被代理的行为是卖票
1
2
3
4// Seller 售票
type Seller interface {
Sell(name string)
} -
正常情况是火车站卖票
1
2
3
4
5
6
7
8
9
10
11
12
13// Station 火车站
type Station struct {
stock int //库存
}
func (station *Station) Sell(name string) {
if station.stock > 0 {
station.stock--
fmt.Printf("%s purchased 1 ticket, %d remaining\n", name, station.stock)
} else {
fmt.Println("tickets are sold out")
}
} -
而使用代理点卖票
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15// StationProxy 火车代理点
type StationProxy struct {
station *Station // 持有一个火车站对象
}
func (proxy *StationProxy) Sell(name string) {
if proxy.station.stock > 0 {
proxy.station.stock--
fmt.Printf("%s purchased 1 ticket, %d remaining\n", name, proxy.station.stock)
} else {
fmt.Println("tickets are sold out")
}
}
var _ Seller = (*StationProxy)(nil)
单元测试
1 | func TestStationProxy_sell(t *testing.T) { |
运行的结果是
1 | A purchased 1 ticket, 2 remaining |
总结
- 延迟初始化, 如果有一个偶尔使用的重量级服务对象,一直保持该对象运行会消耗系统资源时使用代理模式(类似单例模式,但单例模式强调的是单实例)
- 访问控制(保护代理),如果你只希望特定客户端使用服务对象,这里的对象可以是操作系统中非常重要的部分,而客户端则是各种已启动的程序(包括恶意程序),此时可使用代理模式