【设计模式】第七章:代理模式详解及应用案例

这篇具有很好参考价值的文章主要介绍了【设计模式】第七章:代理模式详解及应用案例。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

系列文章

【设计模式】七大设计原则
【设计模式】第一章:单例模式
【设计模式】第二章:工厂模式
【设计模式】第三章:建造者模式
【设计模式】第四章:原型模式
【设计模式】第五章:适配器模式
【设计模式】第六章:装饰器模式
【设计模式】第七章:代理模式
【设计模式】第八章:桥接模式
【设计模式】第九章:外观模式 / 门面模式
【设计模式】第十章:组合模式
【设计模式】第十一章:享元模式
【设计模式】第十二章:观察者模式
【设计模式】第十三章:模板方法模式
【设计模式】第十四章:策略模式
【设计模式】第十五章:责任链模式
【设计模式】第十六章:迭代器模式
【设计模式】第十七章:状态模式
【设计模式】第十八章:备忘录模式
【设计模式】第十九章:访问者模式
【设计模式】第二十章:解释器模式
【设计模式】第二十一章:命令模式
【设计模式】第二十二章:中介者模式



一、定义

摘自百度百科: 所谓的代理者是指一个类别可以作为其它东西的接口。代理者可以作任何东西的接口:网上连接、存储器中的大对象、文件或其它昂贵或无法复制的资源。


二、角色分类

抽象主题角色(Subject)

定义了代理角色和真实主题角色的共同接口,代理角色通过该接口调用真实主题角色的方法。

真实主题角色(Real Subject)

实现了抽象主题角色的接口,代表真实的业务对象。

代理角色(Proxy)

实现了抽象主题角色定义的接口,并持有真实主题角色的引用,代表了真实主题角色的代理。在代理角色中,可以添加额外的功能,如记录日志、权限控制等,而这些功能并不是真实主题角色本身所具备的功能

客户(Client)

具体调用代理者的角色


三、UML图

【设计模式】第七章:代理模式详解及应用案例,设计模式,设计模式,代理模式


四、实现方式

需求分析

假如我们有一个这样的场景:我们想要去看电影,但是我们嫌麻烦不想去电影院排队买票,这时候我们可以选择第三方的平台来买票,并且代理会为我们处理一切的购票相关的事务,包括选座、付款等。其实这种模式就相当于我们设计模式中的代理模式,其代理第三方平台,接下来我们用代码来实现一下这个业务。

具体实现

简单实现

抽象主题角色(Subject)

public interface Subject {
  void request();
}

真实主题角色(Real Subject)

public class RealSubject implements Subject {
  public void request() {
    System.out.println("RealSubject: 处理请求中");
  }
}

代理角色(Proxy)

public class Proxy implements Subject {
  private RealSubject realSubject;

  public void request() {
    if (null == realSubject) {
      realSubject = new RealSubject();
    }
    preRequest();
    realSubject.request();
    postRequest();
  }

  private void preRequest() {
    System.out.println("Proxy: 请求前执行逻辑");
  }

  private void postRequest() {
    System.out.println("Proxy: 请求后执行逻辑");
  }
}

客户角色(Client)

public class Client {
  public static void main(String[] args) {
    Subject subject = new Proxy();
    subject.request();
  }
}

运行结果

Proxy:请求前执行逻辑
RealSubject: 处理请求中
Proxy: 请求后处理逻辑

动态代理

我们有一个接口 Subject 和其一个实现类 RealSubject,我们要使用JDK的动态代理来生成一个代理对象Proxy,代理对象的调用会转发给RealSubject对象。

抽象主题角色(Subject)

public interface Subject {
  void request();
}

真实主题角色(Real Subject)

public class RealSubject implements Subject {
  @Override
  public void request() {
    System.out.println("RealSubject: 处理请求中");
  }
}

动态代理角色(DynamicProxy)

public class DynamicProxy implements InvocationHandler {
  private Object realObject;

  public DynamicProxy(Object realObject) {
    this.realObject = realObject;
  }

  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    // 调用前执行
    System.out.println("DynamicProxy: 请求后执行逻辑");

    // 执行实际方法
    Object result = method.invoke(realObject, args);

    // 调用后执行
    System.out.println("DynamicProxy: 请求后执行逻辑");

    return result;
  }
}

客户角色(Client)

public class Client {
  public static void main(String[] args) {
    // 创建被代理对象
    RealSubject realSubject = new RealSubject();

    // 创建代理对象
    Subject proxy = (Subject) Proxy.newProxyInstance(
      realSubject.getClass().getClassLoader,
      realSubject.getClass().getInterfaces(),
      new DynamicProxy(realSubject)
    );

    // 调用代理对象的方法
    proxy.request();
  }
}

运行结果

DynamicProxy: 请求前执行逻辑
RealSubject: 处理请求中
DynamicProxy: 请求后执行逻辑

在上述代码中,RealSubject表示真实的业务实现类,DynamicProxy表示动态代理类,Client表示客户端。我们通过创建RealSubject对象,然后创建一个代理对象proxy来访问RealSubject

在代理对象中,我们实现了InvocationHandler接口,并重写了其中的invoke()方法,在调用代理对象的方法时,invoke()方法会被自动调用。在invoke()方法中,我们可以进行一些额外的操作,比如在调用实际对象的方法前后添加日志等。

使用Proxy.newProxyInstance()方法来创建代理对象。该方法需要传入三个参数:ClassLoader对象,Class对象数组和InvocationHandler对象。其中,ClassLoader对象用于加载代理类,Class对象数组表示代理类需要实现的接口列表,InvocationHandler对象用于处理代理对象的方法调用。


五、应用场景

以下部分内容摘自菜鸟教程

意图: 为其他对象提供一种代理,以控制对这个对象的访问。

主要解决: 解决了在直接访问对象时带来的问题,比如说:要访问的对象在远程的机器上。在面向对象系统中,有些对象由于某些原因(比如对象创建开销很大,或者某些操作需要安全控制,或者需要进程外的访问),直接访问会给使用者或者系统结构带来很多麻烦,我们可以在访问此对象时加上一个对此对象的访问层。

何时使用: 想在访问一个类时做一些控制。

如何解决: 增加中间层。

关键代码: 实现与被代理类组合。

应用实例:

  1. Windows中的快捷方式
  2. 猪八戒去找高翠兰,结果却是孙悟空变的,可以这样理解:把高翠兰的外貌抽象出来,高翠兰本人和孙悟空都实现了这个接口,猪八戒在访问高翠兰的时候看不出来这个是悟空,所以此时孙悟空是高翠兰的代理类
  3. 买火车票不一定在火车站买,也可以去代售点
  4. 一张支票或银行存单是账户中资金的代理。支票在市场交易中用来替代现金,并提供对签发账号上资金的控制
  5. Spring AOP

适用场景:

按职责划分通常有以下场景:

  1. 远程代理
  2. 虚拟代理
  3. Copy-on-Write代理
  4. 保护(Protect or Access)代理
  5. Cache代理
  6. 防火墙(Firewall)代理
  7. 同步化(Synchronization)代理
  8. 智能引用(Smart Reference)代理

注意事项:

  1. 和适配器模式区别:适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口
  2. 与装饰器的区别:装饰器模式为了增强功能,而代理模式是为了加以控制

六、优缺点

优点

  1. 职责清晰
  2. 扩展性高
  3. 智能化

缺点

  1. 由于在客户端和真实主题中间加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢
  2. 实现代理模式需要额外的工作,有些代理模式的实现非常复杂

推荐

关注博客和公众号获取最新文章

Bummon’s Blog | Bummon’s Home | 公众号文章来源地址https://www.toymoban.com/news/detail-525415.html

到了这里,关于【设计模式】第七章:代理模式详解及应用案例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于FPGA的UDP协议栈设计第七章_RGMII模块设计

    该部分内容主要需要掌握各种IO和时钟相关的原语使用 以太网的通信离不开PHY芯片,PHY芯片实现实现了RGMII接口到网口(RJ45)的转换, RGMII接口就是PHY芯片和FPGA之间的接口。 GMII :GMII(Gigabit Media Independant Interface),千兆MII接口。GMII采用8位接口数据,工作时钟125MHz,因此传

    2024年04月15日
    浏览(78)
  • 智能寻迹避障清障机器人设计(第七章)

    本课题的智能小车实现了红外与蓝牙双控,可以通过红外遥控器或者蓝牙遥控器使智能小车实现调速、前进、后退、左转、右转、左旋转、右旋转、机械臂上下左右运动以及夹子的张闭,可以抓取搬运物品。除此之外,智能小车还具备了寻迹功能,可以根据黑线进行寻迹;避

    2024年01月17日
    浏览(39)
  • 中文编程入门(Lua5.4.6中文版)第七章 Lua 字符串与模式

    在网游的符文之地中,我们可以通过神秘的“字符串法术”来处理和操作一系列字符。以下是如何在Lua的魔法卷轴上施展这种法术: 字符串的表示与召唤:  在Lua的魔法治则中,你可以运用三种方式召唤出一串字符(即字符串): 单引号(\\\')内的字符序列。 双引号(\\\")内的字符

    2024年03月19日
    浏览(37)
  • python第七章(字典)

    一。字典(类型为dict)的特点: 1.符号为大括号 2.数据为键值对形式出现 3.各个键值对之间以逗号隔开 格式:str1={\\\'name\\\':\\\'Tom\\\'}  name相当于键值(key),Tom相当于值 二。空字典的创建方法 三。字典的基本操作(增删改查) 1.字典的增加操作:字典序列[key] = 值 注意点:如果存

    2024年01月24日
    浏览(56)
  • 第七章金融中介

             金融中介是通过向资金盈余者发行 间接融资合约( 如存款单),并和资金短缺者达成 间接投资合约 (发放信贷)或购买其发行的证券,在资金供求方之间融通资金,对资金跨期、跨域进行优化配置的金融机构。         金融体系由金融市场和金融中介构成,以银行业为

    2024年02月04日
    浏览(55)
  • 第七章 图论

    第七章 图论 一、数据结构定义 图的邻接矩阵存储法 图的邻接表存储法 把所有节点存储为节点数组,每个节点里有自己的数据和一个边指针,这个边指针相当于一个链表的头指针,这个链表里存放所有与这个节点相连的边,边里存放该边指向的节点编号和下一条边指针 图的

    2024年02月14日
    浏览(88)
  • 数据结构第七章

    图(Graph)G由两个集合V和E组成,记为G=(V, E),其中V是顶点的有穷非空集合,E是V中顶点偶对的有穷集合,这些顶点偶对称为边。V(G)和E(G)通常分别表示图G的顶点集合和边集合,E(G)可以为空集。若EG)为空,则图G只有顶点而没有边。 子图:假设有两个图G=(V,E)和G1=(V1,E1);如果V1

    2024年02月03日
    浏览(62)
  • 第七章 函数矩阵

    和矩阵函数不同的是,函数矩阵本质上是一个矩阵,是以函数作为元素的矩阵。 矩阵函数本质上是一个矩阵,是以矩阵作为自变量的函数。 函数矩阵和数字矩阵的运算法则完全相同。 不过矩阵的元素 a i j ( x ) a_{ij}(x) a ij ​ ( x ) 需要是闭区间 [ a , b ] [a,b] [ a , b ] 上的实函数

    2024年02月04日
    浏览(58)
  • 第七章 测试

    7.1.1 选择程序设计语言 1. 计算机程序设计语言基本上可以分为汇编语言和高级语言 2. 从应用特点看,高级语言可分为基础语言、结构化语言、专用语言 01 有理想的模块化机制; 02 可读性好的控制结构和数据结构; 03 便于调试和提高软件可靠性; 04 编译程序发现程序错误的

    2024年02月08日
    浏览(77)
  • [JavaScript] 第七章 对象

    🌹作者主页:青花锁 🌹简介:Java领域优质创作者🏆、Java微服务架构公号作者😄 🌹简历模板、学习资料、面试题库、技术互助 🌹文末获取联系方式 📝 [Java项目实战] 介绍Java组件安装、使用;手写框架等 [Aws服务器实战] Aws Linux服务器上操作nginx、git、JDK、Vue等 [Java微服务

    2024年02月02日
    浏览(129)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包