找回密码
 立即注册
首页 业界区 业界 【代理设计模式详解】C/Java/JS/Go/Python/TS不同语言实 ...

【代理设计模式详解】C/Java/JS/Go/Python/TS不同语言实现

寂傧 2025-6-6 09:43:22
简介

代理模式(Proxy Pattern)是一种结构型设计模式,用一个类来代理另一个类或几个类的功能。
在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。
延迟初始化(虚拟代理)。如果你有一个偶尔使用的重量级服务对象,一直保持该对象运行会消耗系统资源时,可使用代理模式。
访问控制(保护代理)。如果你只希望特定客户端使用服务对象,这里的对象可以是操作系统中非常重要的部分,而客户端则是各种已启动的程序 (包括恶意程序), 此时可使用代理模式。
作用


  • 为其他对象提供一种代理访问的方式。
  • 避免直接访问可能带来的问题,通过接口和代理来实现高扩展。
实现步骤


  • 定义一个基础接口,约定一些方法。
  • 建立原始类,实现接口方法。
  • 再建立代理类,也实现基础接口。代理类调用原始类来实现功能。
UML

1.png
 
Java代码

代理接口类
  1. // Image.java 定义一个接口供代理和实际调用来使用
  2. public interface Image {
  3.   void display();
  4. }
复制代码
功能代理类
  1. // ProxyImage.java 代理类也实现了基础接口
  2. public class ProxyImage implements Image {
  3.   private RealImage realImage;
  4.   private String fileName;
  5.   public ProxyImage(String fileName) {
  6.     this.fileName = fileName;
  7.   }
  8.   @Override
  9.   public void display() {
  10.     System.out.println("ProxyImage::display() " + fileName);
  11.     if (realImage == null) {
  12.       realImage = new RealImage(fileName);
  13.     }
  14.     // 代理类调用真实类的方法
  15.     realImage.display();
  16.   }
  17. }
复制代码
真实功能类
  1. // RealImage.java 真实类也实现基础代理接口
  2. public class RealImage implements Image {
  3.   private String fileName;
  4.   public RealImage(String fileName) {
  5.     // 在初始化时执行内部逻辑
  6.     this.fileName = fileName;
  7.     loadFromDisk(fileName);
  8.   }
  9.   @Override
  10.   public void display() {
  11.     System.out.println("RealImage::display() " + fileName);
  12.   }
  13.   // 这个方法只是内部使用
  14.   private void loadFromDisk(String fileName) {
  15.     System.out.println("RealImage::loadFromDisk()  " + fileName);
  16.   }
  17. }
复制代码
测试调用
  1.   /**
  2.    * 代理模式就是用一个类来代理另一个类或几个类的功能,以便隔绝外部客户和内部真实类
  3.    * 这样真实类和调用方之间有一个代理屏障,保证了安全
  4.    * 同时真实的类如果初始化过,就不再初始化,提升了性能
  5.    */
  6.     // 声明代理类来执行真实类的能力
  7.     Image image = new ProxyImage("001.jpg");
  8.     // 代理类执行真实类的能力
  9.     image.display();
  10.     // 再调用一次,不会重复实例化
  11.     image.display();
复制代码
Go代码

代理接口类
  1. // Image.go 定义一个接口供代理和实际调用来使用
  2. type Image interface {
  3.   Init(fileName string)
  4.   Display()
  5. }
复制代码
功能代理类
  1. // ProxyImage.go 代理类也实现了基础接口
  2. type ProxyImage struct {
  3.   fileName string
  4.   // 直接聚合真实类
  5.   // realImage RealImage
  6.   // 聚合接口
  7.   realImage Image
  8. }
  9. // 设置文件名称
  10. func (p *ProxyImage) SetFileName(fileName string) {
  11.   p.fileName = fileName
  12. }
  13. func (p *ProxyImage) Display() {
  14.   fmt.Println("ProxyImage::Display() " + p.fileName)
  15.   if p.realImage == nil {
  16.     p.realImage = &RealImage{}
  17.     p.realImage.Init(p.fileName)
  18.   }
  19.   // 代理类调用真实类的方法
  20.   p.realImage.Display()
  21. }
复制代码
真实功能类
  1. // RealImage.go 真实类也实现基础代理接口
  2. type RealImage struct {
  3.   fileName string
  4. }
  5. // 在初始化时执行内部逻辑
  6. func (r *RealImage) Init(fileName string) {
  7.   r.fileName = fileName
  8.   r.LoadFromDisk(fileName)
  9. }
  10. func (r *RealImage) Display() {
  11.   fmt.Println("RealImage::Display() " + r.fileName)
  12. }
  13. // 这个方法只是内部使用
  14. func (r *RealImage) LoadFromDisk(fileName string) {
  15.   fmt.Println("RealImage::LoadFromDisk()  " + fileName)
  16. }
复制代码
测试调用
  1. func main() {
  2.   fmt.Println("test start:")
  3.   /**
  4.    * 代理模式就是用一个类来代理另一个类或几个类的功能,以便隔绝外部客户和内部真实类
  5.    * 这样真实类和调用方之间有一个代理屏障,保证了安全
  6.    * 同时真实的类如果初始化过,就不再初始化,提升了性能
  7.    */
  8.   // 声明代理类来执行真实类的能力
  9.   var image = &src.ProxyImage{}
  10.   image.SetFileName("001.jpg")
  11.   // 代理类执行真实类的能力
  12.   image.Display()
  13.   // 再调用一次,真实类不会重复实例化
  14.   image.Display()
  15. }
复制代码
C代码简版
  1. // simple_proxy.c
  2. #include <stdio.h>
  3. // 代理模式就是用一个类来代理另一个类或几个类的功能,以便隔绝外部客户和内部真实类
  4. // 定义接口
  5. typedef struct Interface
  6. {
  7.     void (*method)(struct Interface *interface);
  8. } Interface;
  9. // 实现接口的具体类
  10. typedef struct Concrete
  11. {
  12.     void (*method)(struct Concrete *interface);
  13. } Concrete;
  14. void real_method(struct Concrete *interface)
  15. {
  16.     printf("调用真实方法 real_method.\n");
  17. }
  18. // 代理类,继承接口,聚合具体类实例
  19. typedef struct Proxy
  20. {
  21.     struct Interface *real_subject;
  22. } Proxy;
  23. // 代理类方法实现,通过聚合的具体类实例来调用具体类的方法
  24. void proxy_method(struct Interface *interface)
  25. {
  26.     struct Proxy *p = (struct Proxy *)interface;
  27.     p->real_subject->method((struct Interface *)p);
  28. }
  29. int main()
  30. {
  31.     // 创建具体类实例
  32.     struct Concrete real_subject = {
  33.         .method = &real_method,
  34.     };
  35.     // 创建代理类实例并聚合具体类实例
  36.     struct Proxy proxy_instance = {
  37.         .real_subject = (struct Interface *)&real_subject,
  38.     };
  39.     // 将代理类的方法指针指向代理类的方法实现
  40.     struct Interface proxy_interface = {
  41.         .method = &proxy_method,
  42.     };
  43.     // 通过代理类的接口调用具体类方法
  44.     proxy_interface.method((struct Interface *)&proxy_instance);
  45.     return 0;
  46. }
复制代码
更多语言版本

不同语言实现设计模式:https://github.com/microwind/design-pattern

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册