欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

Java23种设计模式系列之代理模式(常用)

时间:2023-07-08

目录

一、代理模式

二、静态代理

三、动态代理(为了解决静态代理的缺点)


一、代理模式

1.什么是代理模式?

代理模式就是给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。

通俗的来讲代理模式就是我们生活中常见的中介。

举例说明,假如说我现在想买一辆二手车,虽然我可以自己去找车源,做质量检测等一系列的车辆过户流程,但是这确实太浪费我得时间和精力了。我只是想买一辆车而已为什么我还要额外做这么多事呢?于是我就通过中介公司来买车,他们来给我找车源,帮我办理车辆过户流程,我只是负责选择自己喜欢的车,然后付钱就可以了。用图表示如下

特征:代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。

代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。

代理模式(Proxy)结构图

 Subject类,定义了RealSubject和Proxy的共用接口,这样就可在任何使用RealSubject的地方可以使用Proxy。(可称为抽象角色)

RealSubject类,定义了Proxy所代表的真是实体(也就是上述所说的委托类,称为真是角色)

Proxy类,保存了一个引用使得代理可以访问实体,并提供了一个与Subjet的接口相同的接口,这样代理就可以用来替代实体。(中介,称为代理角色)

 

2.为什么要用代理模式?

1)开闭原则,增加功能(代理模式在不修改原有代码的基础上,通过代理类扩展委托类的功能。)

比如:我们想给项目加入缓存、日志这些功能,我们就可以使用代理类来完成,而没必要打开已经封装好的委托类。

2)中介隔离作用

(在某些情况下,一个客户类不想或者不能直接引用一个委托对象,而代理类对象可以在客户类和委托对象之间起到中介的作用,其特征是代理类和委托类实现相同的接口。)

3.有哪几种代理模式?

1)静态代理

由程序员创建或特定工具自动生成源代码,在对其编译。在程序运行之前,代理类.class文件就已经被创建了

2)动态代理

能够在程序运行时JVM才为被代理对象生成代理对象。

二、静态代理

简单代码实现:

// 接口 interface IStar { void sing(); } // 真实对象 class LDHStar implements IStar { @Override public void sing() { System.out.println("刘德华唱歌"); } } // 代理类需要有真实对象的控制权 (引用) class ProxyManger implements IStar { // 真实对象的引用 private IStar star; public ProxyManger() { super(); } public ProxyManger(IStar star) { super(); this.star = star; } @Override public void sing() {      System.out.println("唱歌前准备");     star.sing();     System.out.println("善后工作"); } }class Test{public static void main(String[] args) { // 创建明星对象 IStar ldh = new LDHStar(); ProxyManger proxy = new ProxyManger(ldh); proxy.sing(); }}

结果:

 

静态代理总结:
优点:可以做到在不修改目标对象的功能前提下,对目标功能扩展.
缺点:因为代理对象需要与目标对象实现一样的接口,所以会有很多代理类,类太多.同时,一旦接口增          加方法,目标对象与代理对象都要维护.

三、动态代理(为了解决静态代理的缺点)

1.动态代理和静态代理角色一样
2.动态代理的代理类是动态生成的,不是我们直接写好的
3.动态代理分为两大类:基于接口的动态代理,基于类的动态代理
         基于接口----JDK动态代理
         基于类----cglib
         java字节码实现---javasist

需要了解的两个类:

invocationHandle类:调用处理程序,返回结果

proxy类:提供创建动态代理类和实例的静态方法

//目标类接口interface IDog{ void run();}//目标类class GunDog implements IDog{ @Override public void run() { System.out.println("猎狗在跑"); }}class DogUtils{ public static void method1() { System.out.println("增强方式一"); } public static void method2() { System.out.println("增强方式二"); }}class MyInvocationHandle implements InvocationHandler{ private Object target; public void setTarget(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { DogUtils.method1(); method.invoke(target, args); DogUtils.method2(); return null; }} //生产代理对象的工厂 class MyProxyFactory{ public static Object getProxy(Object target) { MyInvocationHandle handle = new MyInvocationHandle(); handle.setTarget(target); Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), handle); return proxy; } }public class ProxyDemo { public static void main(String[] args) { IDog dog = new GunDog(); IDog proxy =(IDog) MyProxyFactory.getProxy(dog); proxy.run(); }}

结果:

 总结:代理对象不需要实现接口,但是目标对象一定要实现接口,否则不能使用动态代理,因此这也算是这种方式的缺陷。

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。