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

news/2024/4/19 8:37:16/文章来源:https://blog.csdn.net/jiarry/article/details/130357554

简介

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

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

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

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

作用

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

实现步骤

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

UML

proxy-pattern.png

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;}@Overridepublic 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);}@Overridepublic 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 = fileNamer.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

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_103759.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

FPGA基础知识 LCMXO3LF-6900C-6BG400I FPGA可编程逻辑简介

FPGA是英文Field&#xff0d;Programmable Gate Array的缩写&#xff0c;即现场可编程门阵列&#xff0c;它是在PAL、GAL、CPLD等可编程器件的基础上进一步发展的产物。它是作为专用集成电路&#xff08;ASIC&#xff09;领域中的一种半定制电路而出现的&#xff0c;既解决了定…

喜报 | ScanA内容安全云监测获评“新一代信息技术创新产品”

4月20日&#xff0c;在赛迪主办的2023 IT市场年会上&#xff0c;“年度IT市场权威榜单”正式发布。 知道创宇的ScanA内容安全云监测产品荣获“新一代信息技术创新产品”奖项。作为中国IT业界延续时间最长的年度盛会之一&#xff0c;历届IT市场年会公布的IT市场权威榜单已成为市…

状态模式——随遇而安

● 状态模式介绍 状态模式中的行为是由状态来决定的&#xff0c;不用的状态下有不同的行为。状态模式和策略模式结构几乎完全一样&#xff0c;但它们的目的、本质却完全不一样就。状态模式的行为是平行的、不可替代的&#xff0c;策略模式的行为是彼此孤立、可相互替换的。用一…

微分方程数值解法(Runge-Kutta法PLC实现)

微分方程数值解法之欧拉法请参看下面的博客文章: 微分方程数值解法(PID仿真用一阶被控对象库PLC算法实现)_数学微积分算法plc编程实例_RXXW_Dor的博客-CSDN博客微分方程除极特殊情况外,大部分不可能求出它的精确解,只能用各种近似方法得到满足一定精度的近似解,微分方程由…

web端导航菜单系列

导航菜单属于导航中最常规的一种导航模式&#xff0c;它有2个显而易见的用途&#xff1a;帮助我们找到想要的任何东西和告诉我们现在身在何处。帮助用户在不同页面之间跳转找到目标功能。 导航作为网站或者平台的骨架&#xff0c;是产品设计中不容忽视的一环。结合自身对于导航…

如何建立Linux与git的连接?

文章目录 建立连接三板斧&#xff1a; 本文以Xshell为案例进行与git的连接&#xff01; 建立连接三板斧&#xff1a; add , commit ,push Linux与git远程连接的方法&#xff1a; 1.设置全局的用户名和邮箱 git config – global user.name “你的用户名” git config – glo…

Springboot Mybatis使用pageHelper实现分页查询

以下介绍实战中数据库框架使用的是mybatis&#xff0c;对整合mybatis此处不做介绍。 使用pageHelper实现分页查询其实非常简单&#xff0c;共两步&#xff1a; 一、导入依赖&#xff1b; 二、添加配置&#xff1b; 那么开始&#xff0c; 第一步&#xff1a; pom.xml添加依…

不得不的创建型模式-原型模式

原型模式是一种创建型模式&#xff0c;它通过复制一个已有对象来创建新的对象&#xff0c;而无需知道新对象的具体类型。 原型模型的结构&#xff1a; 下面是一个简单的C实现原型模式的代码示例&#xff1a; #include <iostream> #include <string> #include <…

ChatGLM ptuning 的实战方案

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…

LVS+keepalived 群集

Keepalived及其工作原理 Keepalived 是一个基于VRRP协议来实现的LVS服务高可用方案&#xff0c;可以解决静态路由出现的单点故障问题 在一个LVS服务集群中通常有主服务器&#xff08;MASTER&#xff09;和备份服务器&#xff08;BACKUP&#xff09;两种角色的服务器&#xff…

tongweb

13051667606 东方通产品介绍 产品兼容 硬件要求 安装 安装目录结构 启动tongweb 停止tongweb bin下常用命令 企业版管理控制台 文档&#xff1a;产品简介及安装指南 绿色版直接解压安装 tar -zxvf …tar.gz Tongweb的配置文件 在conf的tongweb.xml 修改端口等信息 通过页面…

宁波博视眼科俞存院长:晒太阳会晒出白内障?是真的吗?

春意渐浓&#xff0c;人们纷纷踏出家门&#xff0c;享受暖暖的阳光。众所周知&#xff0c;适当晒太阳可以促进人体合成维生素D&#xff0c;对身体有一定的好处。 但你知道吗?太阳光中的紫外线可能会导致部分眼病的出现&#xff0c;例如&#xff1a;白内障。 晒太阳怎么会晒出白…

028:Mapbox GL 绘制线段,实时测量长度距离值

第028个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+mapbox中添加draw组件,绘制线段,编辑线段,实时显示长度值。这里使用turf来计算长度值,采用默认的单位千米。 直接复制下面的 vue+mapbox源代码,操作2分钟即可运行实现效果 文章目录 示例效果配置方式示例源代…

使用WireShark抓包分析TCP_IP协议

文章目录 前言一、TCP/IP协议1.1 OSI分层1.2 TCP/IP 分层 二、抓包2.1 Socket代码2.2 过滤包 三、分析3.1 TCP首部3.2 实战分析3.3 三次握手3.4 四次挥手 参考 前言 TCP/IP 协议 是一组用于互联网通信的协议。它由两个主要协议组成&#xff1a;传输控制协议&#xff08;TCP&am…

RabbitMq-接收消息+redis消费者重复接收

在接触RammitMQ时&#xff0c;好多文章都说在配置中设置属性 # rabbitmq 配置 rabbitmq:host: xxx.xxx.xxx.xxxport: xxxxusername: xxxpassword: xxxxxx## 生产端配置# 开启发布确认,就是confirm模式. 消费端ack应答后,才将消息从队列中删除#确认消息已发送到队列(Queue)pub…

排查和解决CentOS系统上Nacos服务启动报错“java.net.UnknownHostException: jmenv.tbsite.net“问题

背景 环境是CentOS7操作系统&#xff0c;nacos服务宕掉了&#xff0c;启动服务的时候报错。 Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.web.servlet.FilterRegistrationBean]: Factory method ‘di…

大数据管理中心规划设计方案(ppt可编辑)

本资料来源公开网络&#xff0c;仅供个人学习&#xff0c;请勿商用&#xff0c;如有侵权请联系删除。 统一汇聚 推动业务数据协同5 价值提炼 支撑精准服务与科学管理6 实时感知 辅助城市治理高效运行7 大数据资源平台目标体系规划11 建设目标与思路12 使能高效协同&#xff0…

Qt+MySql开发笔记:Qt5.9.3的msvc2017x64版本编译MySql8.0.16版本驱动并Demo连接数据库测试

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/130381428 红胖子网络科技博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬…

【数据结构初阶】第七节.树和二叉树的基本操作

作者简介&#xff1a;大家好&#xff0c;我是未央&#xff1b; 博客首页&#xff1a;未央.303 系列专栏&#xff1a;Java初阶数据结构 每日一句&#xff1a;人的一生&#xff0c;可以有所作为的时机只有一次&#xff0c;那就是现在&#xff01;&#xff01;&#xff01; 文章目…

港科夜闻|香港科技大学(广州)与中国电信广东公司签署战略合作协议

关注并星标 每周阅读港科夜闻 建立新视野 开启新思维 1、香港科技大学(广州)与中国电信广东公司签署战略合作协议。根据协议&#xff0c;双方将围绕各自科技创新及发展需要&#xff0c;整合双方的优质资源和优势能力&#xff0c;务实开展多方位的战略合作。本次合作&#xff0c…