黄小华的个人网站
熬过无人问津的日子才有诗和远方!
设计模式之代理模式

设计模式之代理模式

设计模式来源于生活,每一种设计模式在现实世界中都能有与它相关的处理方式,
关于代理模式,我们听到的见到的最多的可能就是静态代理、动态代理之类的,
代理模式的定义:代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问。
UML结构图如下:

代理模式的应用

代理模式(Proxy)为另一个对象提供一个替身或占位符以控制对这个对象的访 问,简而言之就是用一个对象来代表另一个对象。

静态代理

编译时执行就创建好代理类

在代理类中注入依赖,即引入需要代理的实体类,通过代理类来调用实体类中的方法来实现静态代理。
静态代理由我们自己去生成固定的代码进行编译。需要定义接口或抽象的父类作为抽象目标类,
具体目标类和代理类一起实现相同的接口或继承相同的类,然后通过调用相同的方法来调用目标对象的方法。
静态代理需要目标对象和代理对象实现相同的接口。可以在不修改目标对象功能的前提下,对目标功能进行扩展。
虽然静态代理可以很好的对目标对象进行功能扩展,但对每一个服务都需要建立代理类,工作量较大且不易管理,
而且如果接口发生改变的话,代理类也得进行相应的修改,这时动态代理的作用就显现出来了。
优点:业务类只需要关注逻辑本身,保证了业务类的重用性。这是代理的共有优点
缺点:1.代理对象的一个借口只服务一种类型的对象,如果要代理的方法很多,
就要为每一种方法苏进行代理,静态代理在程序规模大是就无法胜任
2.如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也
需要实现此方法。增加了代码维护的复杂度

动态代理

运行时执行来创建代理类

动态代理与静态代理的区别在于:在程序运行时,动态代理类是运用反射机制创建而成的。
在抽象工厂模式的最后有提到用反射来代理switch语句进行选择,这里就运用到了类似的思想。
通过动态代理,我们不再需要手动创建代理类,只需编写一个动态处理器即可,而真正的代理对象
由JDK在运行时帮我们创建。所以我们也将之称为JDK动态代理。

优点:最大的好处是接口中声明的所有方法都被转移到调用处理器一个集中的方法中处理(invocation Handler.invoke)。
这样,在接口方法数量比较多的时候,可以进行灵活处理,而不需要想静态代理那样每一个方法进行中转。
缺点:始终无法摆脱仅支持interface代理的局限
相比于静态代理,动态代理的优势很明显的,不仅减少了对业务接口的依赖,还降低了耦合度,
但它还是无法摆脱对接口的依赖

使用场景

远程代理。为一个对象在不同的地址空间提供局部代表
虚拟代理。根据需要创建开销很大的对象,通过它来存放实例化需要很长时间的真实对象
安全代理。用来控制真实对象访问时的权限
智能指引,当调用真实的对象时,代理处理另外一些事

应用场景

1.游戏代练


游戏代练应该都听说过,许多人肯定也找过代练,曾经DNF、LOL、王者荣耀等等游戏的代练很多,
当然现在各类游戏层出不穷,也都有各种代练,那这里所谓的代练是什么?就是Proxy,也即代理类,
那游戏代练这件事就是一个代理模式。如果觉得不好理解可以这么想,代练的流程是,你把自己的账号交给代练人员,
让他们帮你打怪升级,而你只需要提供账号即可。那代练人员那边,他所要做的就是登陆你的账号,
然后替你打游戏,从第三者的角度来看,你这个角色在打怪升级,但这个第三者并不知道是不是你本人在打游戏,
他只能看到你这个账号正在打怪升级,但并不需要知道后面打游戏的是谁。这就是代理模式,由他人代理玩游戏。

2.邀请明星,联系其经纪人

我们现在要邀请明星来上节目,我是直接给这个明星打电话吗?当然不是,是给他的经纪人打电话,
然后再由经纪人通知到该明星,这里经纪人充当的就是代理的角色。

3.Windows快捷方式

更常见的例子就是Windows的快捷方式,通过快捷方式,我们可以访问某个文件夹下的exe文件,
这就是一个典型的代理模式,它将接口,按上面游戏的说法说就是代练的账号,提供了出来,
我们只需点击快捷方式,它会帮我们运行指定目录下的指定程序。

4.火车票代售点

5.Spring AOP

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