欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 家装 > 【设计模式】【结构型模式(Structural Patterns)】之代理模式(Proxy Pattern)

【设计模式】【结构型模式(Structural Patterns)】之代理模式(Proxy Pattern)

2025/2/8 21:57:58 来源:https://blog.csdn.net/ido1ok/article/details/144060659  浏览:    关键词:【设计模式】【结构型模式(Structural Patterns)】之代理模式(Proxy Pattern)

1. 设计模式原理说明

代理模式(Proxy Pattern) 是一种结构型设计模式,允许你提供一个替身或占位符对象来控制对另一个对象的访问。代理模式的主要目的是控制对真实对象的访问,可以用来添加额外的功能(如延迟加载、权限检查等),而不改变客户端的代码。代理模式通常涉及四个角色:

  1. Subject(主题接口):定义了RealSubject和Proxy的共同接口,这样在任何使用RealSubject的地方都可以使用Proxy。
  2. RealSubject(真实主题):定义了代理对象代表的真实对象,负责执行实际的业务逻辑。
  3. Proxy(代理):持有对RealSubject的引用,可以通过这个引用调用RealSubject的方法。代理可以在调用前后执行额外的操作,比如权限检查、日志记录等。
  4. Client(客户端):通过Subject接口与RealSubject或Proxy交互。

2. UML 类图及解释

UML 类图
+-------------------+                +-----------------------+
|      Subject      |                |    RealSubject        |
|-------------------|                |-----------------------|
| - request(): void |                | - request(): void     |
+-------------------+                +-----------------------+^                        ^|                        |+------------------------+||
+-----------------------------+  |
|           Proxy             |  |
|-----------------------------|  |
| - subject: Subject          |  |
| - request(): void           |  |
+-----------------------------+  |
类图解释
  • Subject:定义了一个公共接口,使得RealSubject和Proxy可以互换使用。
  • RealSubject:实现了Subject接口,定义了真实的业务逻辑。
  • Proxy:也实现了Subject接口,持有一个指向RealSubject的引用。可以在调用RealSubject的方法之前或之后执行额外的操作,例如权限检查、日志记录等。
  • Client:通过Subject接口与RealSubject或Proxy交互,无需关心具体的实现细节。

3. 代码案例及逻辑详解

Java 代码案例
// 主题接口
interface Subject {void request();
}// 真实主题
class RealSubject implements Subject {@Overridepublic void request() {System.out.println("RealSubject: Handling request.");}
}// 代理
class Proxy implements Subject {private RealSubject realSubject;public Proxy(RealSubject realSubject) {this.realSubject = realSubject;}@Overridepublic void request() {// 在调用真实主题的方法之前,可以添加额外的逻辑checkAccess();realSubject.request();// 在调用真实主题的方法之后,可以添加额外的逻辑logAccess();}private void checkAccess() {System.out.println("Proxy: Checking access prior to firing a real request.");}private void logAccess() {System.out.println("Proxy: Logging the time of request.");}
}// 客户端
public class Client {public static void main(String[] args) {RealSubject realSubject = new RealSubject();Proxy proxy = new Proxy(realSubject);// 客户端通过代理来访问真实主题proxy.request();}
}
C++ 代码案例
#include <iostream>// 主题接口
class Subject {
public:virtual void request() = 0;virtual ~Subject() {}
};// 真实主题
class RealSubject : public Subject {
public:void request() override {std::cout << "RealSubject: Handling request.\n";}
};// 代理
class Proxy : public Subject {
private:RealSubject* realSubject;
public:Proxy(RealSubject* realSubject) : realSubject(realSubject) {}void request() override {checkAccess();realSubject->request();logAccess();}private:void checkAccess() {std::cout << "Proxy: Checking access prior to firing a real request.\n";}void logAccess() {std::cout << "Proxy: Logging the time of request.\n";}
};// 客户端
int main() {RealSubject* realSubject = new RealSubject();Proxy* proxy = new Proxy(realSubject);// 客户端通过代理来访问真实主题proxy->request();delete realSubject;delete proxy;return 0;
}
Python 代码案例
# 主题接口
class Subject:def request(self):raise NotImplementedError# 真实主题
class RealSubject(Subject):def request(self):print("RealSubject: Handling request.")# 代理
class Proxy(Subject):def __init__(self, real_subject: RealSubject):self._real_subject = real_subjectdef request(self):# 在调用真实主题的方法之前,可以添加额外的逻辑self._check_access()self._real_subject.request()# 在调用真实主题的方法之后,可以添加额外的逻辑self._log_access()def _check_access(self):print("Proxy: Checking access prior to firing a real request.")def _log_access(self):print("Proxy: Logging the time of request.")# 客户端
if __name__ == "__main__":real_subject = RealSubject()proxy = Proxy(real_subject)# 客户端通过代理来访问真实主题proxy.request()
Go 代码案例
package mainimport ("fmt"
)// 主题接口
type Subject interface {request()
}// 真实主题
type RealSubject struct{}func (r *RealSubject) request() {fmt.Println("RealSubject: Handling request.")
}// 代理
type Proxy struct {realSubject *RealSubject
}func (p *Proxy) request() {// 在调用真实主题的方法之前,可以添加额外的逻辑p.checkAccess()p.realSubject.request()// 在调用真实主题的方法之后,可以添加额外的逻辑p.logAccess()
}func (p *Proxy) checkAccess() {fmt.Println("Proxy: Checking access prior to firing a real request.")
}func (p *Proxy) logAccess() {fmt.Println("Proxy: Logging the time of request.")
}// 客户端
func main() {realSubject := &RealSubject{}proxy := &Proxy{realSubject: realSubject}// 客户端通过代理来访问真实主题proxy.request()
}

4. 总结

代理模式 是一种结构型设计模式,允许你提供一个替身或占位符对象来控制对另一个对象的访问。这种模式的主要目的是在不改变客户端代码的情况下,添加额外的功能,如延迟加载、权限检查、日志记录等。

主要优点
  1. 职责分离:将复杂的操作封装在代理对象中,使客户端代码更加简洁。
  2. 增强功能:可以在不修改原始对象的情况下,通过代理对象添加额外的功能。
  3. 控制访问:可以限制对真实对象的访问,例如权限检查。
  4. 延迟初始化:可以延迟真实对象的创建,直到真正需要时才创建,从而节省资源。
主要缺点
  1. 增加了系统的复杂性:引入了额外的类和对象,使得系统更加复杂。
  2. 可能影响性能:如果代理对象中的额外操作过于复杂,可能会影响系统的性能。
适用场景
  • 当需要在访问对象时添加额外的操作,如权限检查、日志记录等。
  • 当需要延迟初始化昂贵的对象,以提高系统性能。
  • 当需要控制对对象的访问,例如限制访问次数或频率。
  • 当需要为对象提供一个安全的访问点,例如网络服务的代理。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com