设计模式-代理模式(Proxy Pattern)


文章目录

  • 设计模式-代理模式(Proxy Pattern)
  • 一、定义
  • 二、概念解释
  • 三、场景
  • 四、实现
    • 1、类图
    • 2、代码实现
  • 五、小结
    • 六、动态代理实现
  • 六 总结

一、定义

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

二、概念解释

就是对真实对象的包装,通过包装,不仅能代理实现真实对象提供的服务,还能在提供服务的各个时间节点实现额外的附加功能

三、场景

暗黑破坏神3是一款非常肝的游戏,里面的单个装备最好的就是前缀有太古修饰的,以前玩的时候为了刷太古,不知肝过了多少个春夏秋冬,现在想想这种重复的肝副本我完全可以找个代练帮我肝,这样我能省下大把的时间和留个好肝

四、实现

1、类图

2、代码实现

首先定义一个游戏接口

public interface DiabloThree {/*** 刷超级装备*/void getSuperEquipment();
}

我是真实玩家

public class Player implements DiabloThree{@Overridepublic void getSuperEquipment() {System.out.println("不出太古不睡觉");}
}

代练

public class PlayerProxy implements DiabloThree{private Player player;public PlayerProxy(Player player) {this.player = player;}@Overridepublic void getSuperEquipment() {checkUserCount();player.getSuperEquipment();recordGetSuperEquipmentDate();}private void checkUserCount() {System.out.println("检查下用户的装备刷不刷的动怪");}private void recordGetSuperEquipmentDate() {System.out.println("记录下时间 好知道平均多少年出一件太古");}
}

先自己刷刷到困为止,然后让代练继续刷

@SpringBootTest
public class ProxyTest {@Testpublic void test() {// 我在刷Player player = new Player();player.getSuperEquipment();// 刷不动了 找代练PlayerProxy playerProxy = new PlayerProxy(player);// 代练刷playerProxy.getSuperEquipment();}}

五、小结

以上例子,代练这个代理类是我通过编码在编译前就定义好了的,这种代理就叫做静态代理,很明显静态代理太局限,当前代练在刷装备前检查了账号强度,在刷装备后做了时间记录,如果有另外一个代练,他在刷装备前是不检查账号强度的,而是检查你有没有足够的刷副本的钥匙,然后刷完装备后也不记录,而是截图,那我就得再硬编码一个这样的代练出来,如果又有别的代练在刷装备前后有不同的操作,那就得再敲代码。这种方式很明显笨拙,那有没有我不用自己写代理类,而是可以根据我的需要在程序运行时自动生成符合条件的代理类,答案是肯定的,这种方式就是动态代理

六、动态代理实现

动态代理常用的实现方式有两种,一种是java通过Proxy类和InvocationHandler接口实现的基于实现接口的动态代理,一种是cglib通过其增强器Enchancer基于继承实现的动态代理,本文仅演示java基于接口实现的动态代理

代理类要执行的方法必须实现InvocationHandler接口中的invoke方法 这里我们针对上述的游戏例子 生成一个检查账号的invocationHandler

public class CheckPlayerAccountInvocationHandler<T> implements InvocationHandler {T target;public CheckPlayerAccountInvocationHandler(T target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {checkUserCount();Object o = method.invoke(target, args);recordGetSuperEquipmentDate();return o;}private void checkUserCount() {System.out.println("检查下用户的装备刷不刷的动怪");}private void recordGetSuperEquipmentDate() {System.out.println("记录下时间 好知道平均多少年出一件太古");}
}

使用Proxy类动态生成代理类

@Test
public void DynamicProxyTest() {// 真实玩家Player player = new Player();// 代理类定义的代理方法CheckPlayerAccountInvocationHandler<Player> usePlayerAccountInvocationHandler = new CheckPlayerAccountInvocationHandler<>(player);// newProxyInstance生成代理类// 第一个参数指定使用哪个类加载器将代理类加载到JVM 一般选择跟被代理对象一样的类加载器// 第二个参数指定代理类要实现的接口列表// 第三个参数将方法调用分派到自己实现的调用处理程序DiabloThree proxy = (DiabloThree) Proxy.newProxyInstance(player.getClass().getClassLoader(), new Class<?>[]{DiabloThree.class}, usePlayerAccountInvocationHandler);proxy.getSuperEquipment();
}

六 总结

在实际的开发项目中,该模式最好的体现就是Spring的aop,基于动态代理,aop可以为我们写的接口做统一鉴权、统一日志记录等等,而不需要我们在每一个接口中去做这种重复的逻辑,给我们的开发工作提供了极大的便利

代码地址: https://github.com/LuckyTeemo/design-pattern

设计模式-代理模式(Proxy Pattern)相关推荐

  1. 设计模式——代理模式(Proxy Pattern)之为别人做嫁衣

    代理模式Proxy Pattern 代理模式 1.背景 2.定义 3.特征 4.应用场景 5.实验案例 参考 代理模式 1.背景 假如说我现在想租一间房子,虽然我可以自己去找房源,做卫生检测等一系列的 ...

  2. Java24种设计模式(第二种)--代理模式(Proxy Pattern)

    Java24种设计模式 (第二种) 一.代理模式(Proxy Pattern) 模式逻辑: 什么是代理模式呢?我很忙,忙的没空理你,那你要找我呢就先找我的代理人吧,那代理人总要知道 被代理人能做哪些事 ...

  3. 二十四种设计模式:代理模式(Proxy Pattern)

    代理模式(Proxy Pattern) 介绍 为其他对象提供一个代理以控制对这个对象的访问. 示例 有一个Message实体类,某对象对它的操作有Insert()和Get()方法,用一个代理来控制对这 ...

  4. js设计模式——代理模式proxy

    什么是代理模式 代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问. (可以想象一下明星与经纪人的关系,明星是请求的本体,经纪人就是代理proxy) 如何实现代理模式 代理对象内部含有对本 ...

  5. 设计模式(结构型)之代理模式(Proxy Pattern)

    PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN.因为CSDN也支持MarkDown语法了,牛逼啊! [工匠若水 http://blog.csdn.net/yanbob ...

  6. JAVA设计模式Design Pattern→单例模式Singleton Pattern、工厂模式Factory Pattern、代理模式Proxy Pattern

    私有化构造函数的类可以提供相应的 "接口"(一般就是静态方法)来返回自己的唯一实例供外部调用,像这样的确保只生成一个实例的模式被称作单例模式. 工厂模式,一个模型,用来大规模的生产 ...

  7. 代理模式(Proxy Pattern)

    设计模式 - 吕震宇 .NET设计模式系列文章 薛敬明的专栏 乐在其中设计模式(C#) C#设计模式(13)-Proxy Pattern 一. 代理(Proxy)模式 代理(Proxy)模式给某一个对 ...

  8. C++设计模式--代理模式(Proxy)

    前言 C++相对其他编程语言来说算是比较难的了,相关知识点非常多,并且有些概念理解起来比较困难,对于初学者来说可能会感觉到非常痛苦.随着项目难度的升级,需要不断地优化框架从而使整个结构更具有扩展性,那 ...

  9. 趣谈设计模式 | 代理模式(Proxy):利用代理来控制对象的访问

    文章目录 案例:房屋中介 代理模式 代理模式与装饰器模式 代理模式的应用 远程代理 虚拟代理 安全代理 智能引用代理 写时拷贝代理 总结 完整代码与文档 由于代理模式相较于前面的其他设计模式来说更加简 ...

最新文章

  1. go context剖析之使用技巧
  2. c mysql连接池_在LINUX下用C/C++写了一个连接池(访问MYSQL)的类
  3. 二、数据库设计与操作
  4. mysql 8.0 一条insert语句的具体执行流程分析(三)
  5. Linux下x86_64进程地址空间布局
  6. 32 岁大佬阿里二面,他答 JVM 题的姿势,令面试官很想不通。。。
  7. APScheduler Scheduler
  8. 计算机算法设计与分析 最长递增子序列
  9. 华为Java开发编程最新军规,谁违反谁滚蛋!
  10. k8s中本地存储卷emptyDir、hostPath卷
  11. APP软件下载导航站源码+带后台版/亲测可用
  12. MySQL创建网吧管理系统_java网吧信息管理系统
  13. 第三届上海大学生网络安全大赛 流量分析
  14. Service Temporarily Unavailable
  15. 11万多职场文章技巧ACCESS数据库
  16. 在使用firefly的RK3308的SDK使用buildroot构造文件系统时,遇到OEM分区和userdata不能挂在成功的问题
  17. 用Excel地图可视化——2017世界各国和地区GDP排名(初步统计版)
  18. mysql查询当前用户中所有的表空间_oracle 查看用户所在的表空间
  19. ₣Y2XAEfuV1₳ 这缎,登陸块守,友爱
  20. 风格化半调效果如何制作?教程来了

热门文章

  1. C++ note------模板
  2. 观赛S11的正确打开方式,三星玄龙骑士已经为你准备好了
  3. linux 下gz文件解压命令,Linux解压gz文件的命令怎么写
  4. 【转】常用前端框架(类似Bootstrap)
  5. 大写汉字转阿拉伯数字c语言,C# 将阿拉伯数字转换为大写中文的代码
  6. mysql-05-Redis与MongoDB
  7. 瑞星杀毒软件内存占用真相曝光
  8. Android KeyCode对照表
  9. 前端-如何将网页保存为图片
  10. 无法定位程序输入点__gxx_personality_v0的一个解决方法