设计模式:代理模式(C#、JAVA、JavaScript、C++、Python、Go、PHP)

上一篇《组合模式》                                                                   下一篇《命令模式》

简介:

代理模式,它是一种结构型设计模式,它通过引入一个代理对象来控制对原始对象的访问。代理模式的主要目的是在保持原始对象完整性的同时,提供对原始对象的访问和控制。

代理模式包括以下三个角色:

抽象主题类(Subject):通过接口或抽象类声明真实主题和代理对象实现的业务方法。
真实主题类(Real Subject):实现抽象主题中的具体业务,是代理对象所代表的真实对象,是最终引用的对象。
代理类(Proxy):提供与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。
在代理模式中,代理对象充当访问对象和目标对象之间的媒介,通过代理对象实现对目标对象的访问。被代理的对象可以是远程对象、创建开销大的对象以及需要安全控制的对象。

代理模式可以按照代理的生成时机不同分为静态代理和动态代理。静态代理在编译期就生成代理对象,而动态代理则是在Java运行时动态生成。动态代理又分为JDK动态代理和Cglib动态代理两种。

使用代理模式可以带来很多好处,例如可以控制对原始对象的访问,可以在调用真实对象之前或之后执行一些操作,可以扩展真实对象的功能,可以提供更复杂的接口等。

总之,代理模式是一种非常有用的设计模式,可以帮助我们更好地设计和实现软件系统。

代理模式的使用场景:
1、保护目标对象:客户端只与代理类进行交互,不清楚目标对象的具体细节。这可以保护目标对象不被直接访问,增强了安全性。
2、增强目标对象:代理类可以在目标对象的基础上,对目标对象的功能进行增强。代理对象可以扩展目标对象的功能,实现额外的操作。
3、分离目标对象:代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度,增加了程序的可扩展性。这种分离使得客户端和目标对象的交互更加清晰和灵活。

以上场景中,代理模式通过在客户端和目标对象之间增加一个代理对象,实现对目标对象的访问和控制。代理对象可以提供与目标对象相同的接口,并且内部含有对目标对象的引用,通过代理对象实现对目标对象的访问和控制。

代理模式的创建步骤:
1、定义一个接口,该接口定义了目标对象的所有方法。
2、创建目标对象,实现接口中定义的所有方法。
3、创建代理对象,该对象需要实现与目标对象相同的接口,并在内部持有对目标对象的引用。
4、在代理对象中,重写目标对象的所有方法,并在调用目标对象之前或之后执行一些操作。
5、在客户端代码中,使用代理对象代替目标对象进行操作。

以上步骤是代理模式的基本创建过程,具体实现方式可能会因语言和框架的不同而有所差异。在实际开发中,可以根据具体情况进行调整和优化。

代理模式的优点,主要包括:
1、职责清晰:真实的角色实现实现的业务逻辑,不用关心其他非本职的事务,通过后期的代理完成附件的事务,附带的结果就是编程简洁清晰。
2、高度扩展性:具体主题角色随需求不同可能变为多种,但是只要实现了接口,代理类就可以完全在不做任何修饰的情况下代理各种真实的角色。
3、智能化:代理类可以再运行的时候确定真实的代理主题,这是一种强大的功能。
4、保护目标对象:代理模式能够协调调用者和被调用者,在一定程度上降低了系统的耦合度。同时,代理对象可以在调用真实对象之前或之后执行一些操作,增强了程序的灵活性和可扩展性。

代理模式的缺点,主要包括:
1、代理对象可能会造成请求的处理速度变慢。由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。
2、实现代理模式需要额外的工作。有些代理模式的实现非常复杂,需要编写更多的代码和测试用例来确保代理对象和真实对象之间的通信和交互是正确的。
3、代理对象可能会对真实对象进行过度的控制,使得真实对象无法被正确地使用。
4、在代理模式中,客户端需要知道代理对象的类型和接口,这可能会破坏封装性,使得代码变得不够灵活。

总之,虽然代理模式具有许多优点,但是也有一些缺点需要注意。在使用代理模式时,需要根据具体的应用场景和需求来权衡利弊,并选择合适的代理模式来实现所需的功能。

示例:


一、C#代理模式

以下是一个示例,展示了如何在C#中实现代理模式:

public interface ISubject {  void DoSomething();  
}  public class RealSubject : ISubject {  public void DoSomething() {  Console.WriteLine("RealSubject.DoSomething()");  }  
}  public class Proxy : ISubject {  private ISubject _subject;  public Proxy(ISubject subject) {  _subject = subject;  }  public void DoSomething() {  Console.WriteLine("Proxy.DoSomething()");  _subject.DoSomething();  }  
}  class Program {  static void Main(string[] args) {  ISubject subject = new RealSubject();  Proxy proxy = new Proxy(subject);  proxy.DoSomething(); // Output: Proxy.DoSomething() RealSubject.DoSomething()  }  
}

二、java代理模式

代理模式通常通过以下方式实现:

interface Subject {  void doSomething();  
}  class RealSubject implements Subject {  public void doSomething() {  System.out.println("RealSubject.doSomething()");  }  
}  class Proxy implements Subject {  private Subject _subject;  public Proxy(Subject subject) {  _subject = subject;  }  public void doSomething() {  System.out.println("Proxy.doSomething()");  _subject.doSomething();  }  
}  public class ProxyPatternDemo {  public static void main(String[] args) {  Subject subject = new RealSubject();  Proxy proxy = new Proxy(subject);  proxy.doSomething(); // Output: Proxy.doSomething() RealSubject.doSomething()  }  
}

三、javascript代理模式

在JavaScript中,代理模式的实现方式如下:

class Subject {  constructor() {  this._data = [];  }  addData(data) {  this._data.push(data);  }  getData() {  return this._data;  }  
}  class Proxy {  constructor(subject) {  this._subject = subject;  }  addData(data) {  console.log('Proxy.addData()');  this._subject.addData(data);  }  getData() {  console.log('Proxy.getData()');  return this._subject.getData();  }  
}  const subject = new Subject();  
const proxy = new Proxy(subject);  
proxy.addData('data1'); // Output: Proxy.addData() [ 'data1' ]  
proxy.getData(); // Output: Proxy.getData() [ 'data1' ]

四、C++代理模式

以下是在C++中实现代理模式:

class Subject {  
public:  virtual void doSomething() = 0;  
};  class RealSubject : public Subject {  
public:  void doSomething() override {  std::cout << "RealSubject.doSomething()" << std::endl;  }  
};  class Proxy : public Subject {  
public:  Proxy(Subject* subject) : _subject(subject) {}  void doSomething() override {  std::cout << "Proxy.doSomething()" << std::endl;  _subject->doSomething();  }  
private:  Subject* _subject;  
};  int main() {  RealSubject* realSubject = new RealSubject();  Proxy* proxy = new Proxy(realSubject);  ((Subject*)proxy)->doSomething(); // Output: Proxy.doSomething() RealSubject.doSomething()  delete proxy;  delete realSubject;  return 0;  
}

五、python代理模式

以下是在python中实现代理模式:

class Subject:  def do_something(self):  pass  class RealSubject(Subject):  def do_something(self):  print("RealSubject.do_something()")  class Proxy(Subject):  def __init__(self, real_subject):  self._real_subject = real_subject  def do_something(self):  print("Proxy.do_something()")  self._real_subject.do_something()  if __name__ == "__main__":  real_subject = RealSubject()  proxy = Proxy(real_subject)  proxy.do_something() # Output: Proxy.do_something() RealSubject.do_something()

六、go代理模式

以下是一个示例,展示了如何在go中实现代理模式:

type RealObject struct{}  func (r *RealObject) Operation() {  fmt.Println("RealObject.Operation()")  
}  type ProxyObject struct {  realObj *RealObject  
}  func (p *ProxyObject) Operation() {  fmt.Println("ProxyObject.Operation()")  p.realObj.Operation()  
}  func main() {  realObj := &RealObject{}  proxyObj := &ProxyObject{realObj: realObj}  proxyObj.Operation() // Output: ProxyObject.Operation() RealObject.Operation()  
}

七、PHP代理模式

以下是一个示例,展示了如何在PHP中实现代理模式:

<?php  // 目标接口  
interface Subject {  public function doSomething();  
}  // 目标类  
class RealSubject implements Subject {  public function doSomething() {  echo "RealSubject.doSomething()";  }  
}  // 代理类  
class Proxy implements Subject {  private $realSubject;  public function __construct(RealSubject $realSubject) {  $this->realSubject = $realSubject;  }  public function doSomething() {  echo "Proxy.doSomething()";  $this->realSubject->doSomething();  }  
}  // 客户端代码  
$realSubject = new RealSubject();  
$proxy = new Proxy($realSubject);  
$proxy->doSomething(); // Output: Proxy.doSomething() RealSubject.doSomething()


《完结》

上一篇《组合模式》                                                                   下一篇《命令模式》

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

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

相关文章

《动手学深度学习 Pytorch版》 10.4 Bahdanau注意力

10.4.1 模型 Bahdanau 等人提出了一个没有严格单向对齐限制的可微注意力模型。在预测词元时&#xff0c;如果不是所有输入词元都相关&#xff0c;模型将仅对齐&#xff08;或参与&#xff09;输入序列中与当前预测相关的部分。这是通过将上下文变量视为注意力集中的输出来实现…

【Elasticsearch】es脚本编程使用详解

目录 一、es脚本语言介绍 1.1 什么是es脚本 1.2 es脚本支持的语言 1.3 es脚本语言特点 1.4 es脚本使用场景 二、环境准备 2.1 docker搭建es过程 2.1.1 拉取es镜像 2.1.2 启动容器 2.1.3 配置es参数 2.1.4 重启es容器并访问 2.2 docker搭建kibana过程 2.2.1 拉取ki…

代码训练营第50天:leetcode198打家劫舍|leetcode213打家劫舍2|leetcode337打家劫舍3

leetcode198&#xff1a;打家劫舍 文章讲解&#xff1a;leetcode198 leetcode213&#xff1a;打家劫舍2 文章讲解&#xff1a;leetcode213 leetcode337&#xff1a;打家劫舍3 文章讲解&#xff1a;leetcode337 目录 1&#xff0c;leetcode198 打家劫舍 2&#xff0c;leetcode…

LSKA(大可分离核注意力):重新思考CNN大核注意力设计

文章目录 摘要1、简介2、相关工作3、方法4、实验5、消融研究6、与最先进方法的比较7、ViTs和CNNs的鲁棒性评估基准比较8、结论 摘要 https://arxiv.org/pdf/2309.01439.pdf 大型可分离核注意力&#xff08;LSKA&#xff09;模块的视觉注意力网络&#xff08;VAN&#xff09;已…

Linux CentOS 8(firewalld的配置与管理)

Linux CentOS 8&#xff08;firewalld的配置与管理&#xff09; 目录 一、firewalld 简介二、firewalld 工作概念1、预定义区域&#xff08;管理员可以自定义修改&#xff09;2、预定义服务 三、firewalld 配置方法1、通过firewall-cmd配置2、通过firewall图形界面配置 四、配置…

利用Jpom在线构建Spring Boot项目

1 简介 前面介绍了运用Jpom构建部署Vue项目&#xff0c;最近研究了怎么部署Spring Boot项目&#xff0c;至此&#xff0c;一套简单的前后端项目就搞定了。 2 基本步骤 因为就是一个简单的自研测试项目&#xff0c;所以构建没有使用docker容器&#xff0c;直接用java -jar命令…

Java程序设计进阶

Java异常处理机制 异常 异常的最高父类是 Throwable&#xff0c;在 java.lang 包下。 Throwable 类的方法主要有&#xff1a; 方法说明public String getMessage()返回对象的错误信息public void printStackTrace()输出对象的跟踪信息到标准错误输出流public void printSta…

【项目设计】网络对战五子棋(下)

我不再装模作样地拥有很多朋友&#xff0c;而是回到了孤单之中&#xff0c;以真正的我开始了独自的生活。有时我也会因为寂寞而难以忍受空虚的折磨&#xff0c;但我宁愿以这样的方式来维护自己的自尊&#xff0c;也不愿以耻辱为代价去换取那种表面的朋友。 文章目录 一、项目设…

Postman笔记

文章目录 1.安装2.简介和使用流程3 postman使用3.1 测试集与HTTP请求发送HTTP请求和分析响应数据 3.2 发送HTTP请求和分析响应数据3.3 Postman中请求体提交方式3.4 Postman使用之接口测试3.5 使用Postman新建一个mock服务3.6 请求数据的参数化3.7 断言与脚本导出 1.安装 官网地…

2-Java进阶知识总结-7-UDP-TCP

文章目录 网络编程概述网络编程三要素--IP地址IP地址--概念&#xff08;IP&#xff1a;Internet Protocol&#xff09;IP地址--分类IP地址--特殊的地址&#xff1a;127.0.0.1IP地址获取--DOS命令IP地址获取--InetAddress类 网络编程三要素--端口端口--概念端口号 网络编程三要素…

DP读书:《openEuler操作系统》(五)进程与线程

进程与线程 进程的概念程序&#xff1a;从源码到执行1. 编译阶段:2. 加载阶段:3. 执行阶段: 程序的并发执行与进程抽象 进程的描述进程控制块1. 描述信息2. 控制信息3. CPU上下文4. 资源管理信息 进程状态1.就绪状态2.运行状态3.阻塞状态4.终止状态 进程的控制进程控制源语1.创…

CrossOver23.6软件激活码怎么获取 CrossOver软件2023怎么激活

CrossOver一款类虚拟机&#xff0c;它的主要功能是在mac系统中安装windows应用程序。其工作原理是将exe格式的windows应用程序安装包安装至CrossOver容器中&#xff0c;并将运行该exe文件所需的配置文件下载至容器中&#xff0c;便能在mac正常运行windows应用程序了。下面就让我…

如何构建一个外卖微信小程序

随着外卖行业的不断发展&#xff0c;越来越多的商家开始关注外卖微信小程序的开发。微信小程序具有使用方便、快速上线、用户覆盖广等优势&#xff0c;成为了商家们的首选。 那么&#xff0c;如何快速开发一个外卖微信小程序呢&#xff1f;下面就让我们来看看吧&#xff01; 首…

【C++入门:C++世界的奇幻之旅】

1. 什么是C 2. C发展史 3. C的重要性 4. C关键字 5. 命名空间 6. C输入&输出 7. 缺省参数 8. 函数重载 9. 引用 10. 内联函数 11. auto关键字(C11) 12. 基于范围的for循环(C11) 13. 指针空值---nullptr(C11)05. 1. 什么是C C语言是结构化和模块化的语言&…

什么是web3.0?

Web 3.0&#xff0c;也常被称为下一代互联网&#xff0c;代表着互联网的下一个重大演变。尽管关于Web 3.0的确切定义尚无共识&#xff0c;但它通常被认为是一种更分散、更开放且更智能的互联网。 以下是Web 3.0的一些主要特征和概念&#xff1a; 1. 去中心化 Web 3.0旨在减少…

人工智能:CNN(卷积神经网络)、RNN(循环神经网络)、DNN(深度神经网络)的知识梳理

卷积神经网络&#xff08;CNN&#xff09; 卷积神经网络&#xff08;CNN&#xff09;&#xff0c;也被称为ConvNets或Convolutional Neural Networks&#xff0c;是一种深度学习神经网络架构&#xff0c;主要用于处理和分析具有网格状结构的数据&#xff0c;特别是图像和视频数…

C# 解决“xxx正由另一进程使用,因此该进程无法访问该文件。“的错误

工作中遇到客户想要自己替换软件Logo的问题&#xff0c;本身logo的获取方式最底层是这样的&#xff1a; string path AppDomain.CurrentDomain.BaseDirectory "Image\\" name;if (File.Exists(path)){return new Bitmap(path);} 但是在软件运行时想要更改logo的文…

CSS中 通过自定义属性(变量)动态修改元素样式(以 el-input 为例)

传送门&#xff1a;CSS中 自定义属性&#xff08;变量&#xff09;详解 1. 需求及解决方案 需求&#xff1a;通常我们动态修改 div 元素的样式&#xff0c;使用 :style 和 :class 即可&#xff1b;但想要动态修改 如&#xff1a;Element-ui 中输入框&#xff08;input&#x…

Windows与Linux服务器互传文件

使用winscp实现图形化拖动的方式互传文件. 1.下载winscp软件并安装&#xff0c;官方地址&#xff1a; https://winscp.net/eng/index.php 2.打开软件&#xff1a; 文件协议选择scp&#xff0c;输入linux服务器的IP和端口号&#xff0c;然后输入你的用户名和密码就可以登陆了。…

postman打开后,以前的接口记录不在,问题解决

要不这些文件保存在C:\Users\{用户名}\AppData\Roaming\Postman 比如&#xff0c;你目前使用的window登录用户是abc&#xff0c;那么地址便是C:\Users\abc\AppData\Roaming\Postman 打开后&#xff0c;这个目录下会有一些命名为backup-yyyy-MM-ddThh-mm-ss.SSSZ.json类似的文…