当前位置: 首页 >  网技达人 >  【代理设计模式详解】C/Java/JS/Go/Python/TS不同语言实现

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

导读:简介.代理模式(Proxy Pattern)是一种结构型设计模式,用一个类来代理另一个类或几个类的功能。.在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。.延迟初始化(虚拟代理)。如果你有一个偶尔使用的重量级服务对象,一直保持该对象运行会消耗系统资源时,可使用代

简介

代理模式(Proxy Pattern)是一种结构型设计模式,用一个类来代理另一个类或几个类的功能。

在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。

延迟初始化(虚拟代理)。如果你有一个偶尔使用的重量级服务对象,一直保持该对象运行会消耗系统资源时,可使用代理模式。

访问控制(保护代理)。如果你只希望特定客户端使用服务对象,这里的对象可以是操作系统中非常重要的部分,而客户端则是各种已启动的程序 (包括恶意程序), 此时可使用代理模式。

作用

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

实现步骤

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

UML

Java代码

代理接口类

// Image.java 定义一个接口供代理和实际调用来使用
public interface Image {
  void display();
}

功能代理类

// ProxyImage.java 代理类也实现了基础接口
public class ProxyImage implements Image {

  private RealImage realImage;
  private String fileName;

  public ProxyImage(String fileName) {
    this.fileName = fileName;
  }

  @Override
  public void display() {
    System.out.println("ProxyImage::display() " + fileName);
    if (realImage == null) {
      realImage = new RealImage(fileName);
    }
    // 代理类调用真实类的方法
    realImage.display();
  }
}

真实功能类

// RealImage.java 真实类也实现基础代理接口
public class RealImage implements Image {

  private String fileName;

  public RealImage(String fileName) {
    // 在初始化时执行内部逻辑
    this.fileName = fileName;
    loadFromDisk(fileName);
  }

  @Override
  public void display() {
    System.out.println("RealImage::display() " + fileName);
  }

  // 这个方法只是内部使用
  private void loadFromDisk(String fileName) {
    System.out.println("RealImage::loadFromDisk()  " + fileName);
  }
}

测试调用

  /**
   * 代理模式就是用一个类来代理另一个类或几个类的功能,以便隔绝外部客户和内部真实类
   * 这样真实类和调用方之间有一个代理屏障,保证了安全
   * 同时真实的类如果初始化过,就不再初始化,提升了性能
   */

    // 声明代理类来执行真实类的能力
    Image image = new ProxyImage("001.jpg");

    // 代理类执行真实类的能力
    image.display();

    // 再调用一次,不会重复实例化
    image.display();

Go代码

代理接口类

// Image.go 定义一个接口供代理和实际调用来使用
type Image interface {
  Init(fileName string)
  Display()
}

功能代理类

// ProxyImage.go 代理类也实现了基础接口
type ProxyImage struct {
  fileName string
  // 直接聚合真实类
  // realImage RealImage
  // 聚合接口
  realImage Image
}

// 设置文件名称
func (p *ProxyImage) SetFileName(fileName string) {
  p.fileName = fileName
}

func (p *ProxyImage) Display() {
  fmt.Println("ProxyImage::Display() " + p.fileName)
  if p.realImage == nil {
    p.realImage = &RealImage{}
    p.realImage.Init(p.fileName)
  }
  // 代理类调用真实类的方法
  p.realImage.Display()
}

真实功能类

// RealImage.go 真实类也实现基础代理接口
type RealImage struct {
  fileName string
}

// 在初始化时执行内部逻辑
func (r *RealImage) Init(fileName string) {
  r.fileName = fileName
  r.LoadFromDisk(fileName)
}

func (r *RealImage) Display() {
  fmt.Println("RealImage::Display() " + r.fileName)
}

// 这个方法只是内部使用
func (r *RealImage) LoadFromDisk(fileName string) {
  fmt.Println("RealImage::LoadFromDisk()  " + fileName)
}

测试调用

func main() {
  fmt.Println("test start:")
  /**
   * 代理模式就是用一个类来代理另一个类或几个类的功能,以便隔绝外部客户和内部真实类
   * 这样真实类和调用方之间有一个代理屏障,保证了安全
   * 同时真实的类如果初始化过,就不再初始化,提升了性能
   */

  // 声明代理类来执行真实类的能力
  var image = &src.ProxyImage{}
  image.SetFileName("001.jpg")

  // 代理类执行真实类的能力
  image.Display()

  // 再调用一次,真实类不会重复实例化
  image.Display()
}

C代码简版

// simple_proxy.c
#include <stdio.h>

// 代理模式就是用一个类来代理另一个类或几个类的功能,以便隔绝外部客户和内部真实类

// 定义接口
typedef struct Interface
{
    void (*method)(struct Interface *interface);
} Interface;

// 实现接口的具体类
typedef struct Concrete
{
    void (*method)(struct Concrete *interface);
} Concrete;

void real_method(struct Concrete *interface)
{
    printf("调用真实方法 real_method.\n");
}

// 代理类,继承接口,聚合具体类实例
typedef struct Proxy
{
    struct Interface *real_subject;
} Proxy;

// 代理类方法实现,通过聚合的具体类实例来调用具体类的方法
void proxy_method(struct Interface *interface)
{
    struct Proxy *p = (struct Proxy *)interface;
    p->real_subject->method((struct Interface *)p);
}

int main()
{
    // 创建具体类实例
    struct Concrete real_subject = {
        .method = &real_method,
    };

    // 创建代理类实例并聚合具体类实例
    struct Proxy proxy_instance = {
        .real_subject = (struct Interface *)&real_subject,
    };

    // 将代理类的方法指针指向代理类的方法实现
    struct Interface proxy_interface = {
        .method = &proxy_method,
    };

    // 通过代理类的接口调用具体类方法
    proxy_interface.method((struct Interface *)&proxy_instance);

    return 0;
}

更多语言版本

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

内容
  • 最新消息,powershell,10多年的癌症被治好了!
    最新消息,powershell,
    2023-12-10
    问:癌症是指什么?.答:.powershell一直有个特性,它的管道会传递对象,请看:.‘abc’ | ForEach-
  • RocketMQ消费者是如何负载均衡的
    RocketMQ消费者是如何负载
    2023-12-09
    摘要:RocketMQ 支持两种消息模式:集群消费( Clustering )和广播消费( Broadcasting )
  • Three.js教程:对象克隆、复制
    Three.js教程:对象克隆、
    2023-12-08
    推荐:将 NSDT场景编辑器 加入你的3D工具链.其他系列工具: NSDT简石数字孪生.对象克隆.clone()和复制.
  • FlashDuty Changelog 2023-09-07 | 新增深色模式与主题配置
    FlashDuty Change
    2023-12-04
    FlashDuty:一站式告警响应平台,前往此地址免费体验!.FlashDuty.现在已经全面支持了深色模式,这为您提供
  • git 配置代理  >_>从此告别git clone几KiB/s了
    git 配置代理 >_>从此告
    2023-12-02
    windows 设置代理.http || https协议.//设置全局代理.//http.git config --gl
  • 智能智能保健设备
    智能智能保健设备
    2023-10-04
    智能保健设备产品介绍.产品概述.我们的智能保健设备结合了最新的智能技术和保健功能,旨在帮助用户监控和**自身的健康状况。
  • 智能智能娱乐设备
    智能智能娱乐设备
    2023-10-04
    产品功能介绍.1. 智能娱乐设备.我们的智能娱乐设备是一款结合了智能技术和娱乐功能的产品。它拥有丰富的娱乐资源,包括音乐
  • ***容量规划与扩展服务
    ***容量规划与扩展服务
    2023-10-02
    ***容量规划与扩展服务.产品功能.我们的服务器容量规划与扩展服务旨在帮助客户有效地规划和扩展其服务器容量,以满足不断增
  • 数据分析和挖掘软件
    数据分析和挖掘软件
    2023-10-01
    数据分析和挖掘软件.产品功能.我们的数据分析和挖掘软件提供了丰富的功能,能够帮助用户快速有效地实现数据分析和挖掘,包括数
  • 智能手机
    智能手机
    2023-10-01
    产品功能介绍:智能手机.智能手机是一款集通讯、娱乐、办公等功能于一体的移动智能设备。首先,智能手机具有强大的通讯功能,支
  • 电子元件连接器
    电子元件连接器
    2023-10-02
    电子元件连接器.产品功能.电子元件连接器是一种用于连接不同电子元件的重要组件。它可以提供可*的电气连接,从而实现各种电子
  • *****与保养服务
    *****与保养服务
    2023-10-02
    *****与保养服务.产品介绍.我们的服务器维护与保养服务是为了帮助企业解决***运行过程中出现的各种问题,确保服务器的
  • 智能智能安防设备
    智能智能安防设备
    2023-10-05
    产品介绍.我们的智能安防设备是一款结合了最新科技和人性化设计的智能家居产品。它不仅拥有传*安防设备的监控功能,还具备智能
  • 智能医疗设备
    智能医疗设备
    2023-10-02
    智能医疗设备产品介绍.智能医疗设备是一款集成了先进技术的高科技产品,旨在提高医疗保健的效率和质量。该设备主要应用于医院、
  • ***性能优化服务
    ***性能优化服务
    2023-10-02
    ***性能优化服务.我们的服务器性能优化服务是针对企业和个人用户的***性能提升及优化解决方案。无论您是在使用自己的服务