鱼弦:内容合伙人、新星导师、51CTO(Top红人+专家博主) 、github开源爱好者(go-zero源码二次开发、游戏后端架构 https://github.com/Peakchen)
代理模式原理详细解释:
代理模式(Proxy Pattern)是一种结构型设计模式,通过引入一个代理对象,控制对真实对象的访问。代理对象和真实对象实现相同的接口,客户端通过代理对象来访问真实对象,从而可以在访问前后进行一些额外的操作。
代理模式的核心思想是通过一个代理对象来控制对真实对象的访问。代理对象在客户端和真实对象之间起到了中介的作用,客户端通过代理对象来间接访问真实对象。代理对象可以对真实对象的访问进行控制,例如,可以在访问前后执行一些附加操作,如权限验证、缓存、日志记录等。
底层结构图:
以下是代理模式的经典结构图:
+----------------------------+
| Client |
+----------------------------+
| + Request() |
+----------------------------+
^
|
|
|
|
v
+----------------------------+
| Subject |
+----------------------------+
| + Request() |
+----------------------------+
^
|
|
|
|
v
+----------------------------+
| Proxy |
+----------------------------+
| - subject |
| + Request() |
+----------------------------+
^
|
|
|
|
v
+----------------------------+
| RealSubject |
+----------------------------+
| + Request() |
+----------------------------+
在上述结构图中,Client
是客户端,通过调用 Request()
方法来访问真实对象。
Subject
是真实对象和代理对象共同实现的接口,定义了客户端可以访问的方法。
Proxy
是代理对象,实现了 Subject
接口,并持有一个真实对象的引用。
RealSubject
是真实对象,实现了具体的逻辑,但客户端无法直接访问它。
使用场景解释:
代理模式适用于以下场景:
- 当需要对真实对象的访问进行控制,并在访问前后执行一些额外的操作时,可以使用代理模式。代理对象可以在访问前后进行权限验证、缓存、日志记录等操作。
- 当需要在不修改真实对象的情况下,对其进行扩展或修改时,可以使用代理模式。代理对象可以继承真实对象的接口,并在其基础上增加额外的功能。
- 当真实对象由于某些原因无法直接访问时,可以使用代理模式。代理对象可以在访问真实对象之前进行一些准备工作,如网络连接、初始化等。
代码示例实现:
以下是一个使用Go语言实现代理模式的示例:
package main
import "fmt"
// Subject 接口
type Subject interface {
Request()
}
// RealSubject 真实对象
type RealSubject struct{}
// Request 真实对象的请求
func (r *RealSubject) Request() {
fmt.Println("RealSubject: Handling request")
}
// Proxy 代理对象
type Proxy struct {
realSubject *RealSubject
}
// Request 代理对象的请求
func (p *Proxy) Request() {
if p.realSubject == nil {
p.realSubject = &RealSubject{}
}
p.preRequest()
p.realSubject.Request()
p.postRequest()
}
func (p *Proxy) preRequest() {
fmt.Println("Proxy: Preparing request")
}
func (p *Proxy) postRequest() {
fmt.Println("Proxy: Finishing request")
}
func main() {
proxy := &Proxy{}
proxy.Request()
}
在上述示例中,我们定义了一个接口 Subject
,它包含了代理对象和真实对象共同的方法 Request()
。
RealSubject
是真实对象,实现了具体的请求逻辑。
Proxy
是代理对象,它持有一个真实对象的引用,并在访问前后执行一些额外的操作。
在 main()
函数中,我们创建了代理对象 proxy
,然后调用 proxy.Request()
来访问真实对象。
文献材料链接:
以下是一些有关代理模式的参考文献链接:
- Design Patterns: Elements of Reusable Object-Oriented Software (《设计模式:可复用面向对象软件的基础》) - Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides
链接:Amazon.com - Head First Design Patterns (《深入浅出设计模式》) - Eric Freeman, Elisabeth Robson, Bert Bates, Kathy Sierra
链接:Amazon.com - GoF Design Patterns in Python - Proxy Pattern
链接:Proxy in Python / Design Patterns
当前都有哪些产品在使用:
代理模式被广泛应用于软件开发中,许多产品和框架使用了代理模式来解决各种问题。以下是一些常见的产品和框架,它们使用了代理模式或基于代理模式实现了某些功能:
- Java中的RMI(Remote Method Invocation)框架使用代理模式来支持远程对象的调用和通信。
- Spring框架中的AOP(Aspect-Oriented Programming)模块使用代理模式来实现横切关注点的功能,如事务管理、日志记录等。
- Hibernate框架中的延迟加载(Lazy Loading)机制使用代理模式来实现。
- Java中的动态代理(Dynamic Proxy)机制也是代理模式的一种应用,它允许在运行时创建代理对象并动态地处理对真实对象的调用。