目录
[代理模式(Proxy Pattern)](#代理模式(Proxy Pattern))
代理模式(Proxy Pattern)
代理模式(Proxy Pattern)通过引入代理对象来控制对真实对象的访问。
代理模式的核心角色:
- 抽象主题(Subject):定义了真实对象和代理对象的共同接口,这样在任何使用真实对象的地方都可以使用代理对象。
- 真实主题(Real Subject):定义了代理对象所代表的真实对象。
- 代理(Proxy):保存一个引用使得代理可以访问真实主题,并提供与真实主题相同的接口,以便可以在任何时候替代真实主题。
优缺点
(1)优点:
- 代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用;
- 代理对象可以扩展目标对象的功能;
- 代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度,增加了程序的可扩展性
(2)缺点:
- 代理模式会造成系统设计中类的数量增加
- 在客户端和目标对象之间增加一个代理对象,会造成请求处理速度变慢;
- 增加了系统的复杂度;
使用场景
按职责来划分,通常有以下使用场景:(1)远程代理。 (2)虚拟代理。 (3)Copy-on-Write 代理。 (4)保护(Protect or Access)代理。(5)Cache代理。(6)防火墙(Firewall)代理。 (7)同步化(Synchronization)代理。 (8)智能引用(Smart Reference)代理。
注意事项
- 和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口。
- 和装饰器模式的区别:装饰器模式为了增强功能,而代理模式是为了加以控制。
代码实现
Go
package main
import "fmt"
// 文件下载器,用户可以通过下载器下载文件。为了提高下载速度和安全性,
// 希望引入一个代理对象,代理对象可以在下载前进行权限验证,并记录下载日志。
// 抽象主题:文件接口
type File interface {
Download()
}
// 真实主题:具体文件
type RealFile struct {
filename string
}
func (f *RealFile) Download() {
fmt.Printf("Downloading file: %s\n", f.filename)
}
// 代理:文件代理
type FileProxy struct {
realFile *RealFile
}
func (p *FileProxy) Download() {
p.authenticate()
p.realFile.Download()
p.log()
}
func (p *FileProxy) authenticate() {
fmt.Println("Authenticating user...")
}
func (p *FileProxy) log() {
fmt.Println("Logging download activity...")
}
// 客户端代码
func main() {
file := &FileProxy{
realFile: &RealFile{
filename: "example.txt",
},
}
file.Download()
}