首先我们通过一张图来说明什么是代理模式(后面会有具体的实例):
什么是代理模式?
定义:客户端(Client)不直接调用真实对象,而是通过调用代理对象去调用真实对象。
为什么要用代理模式?:
在某些情况下,一个对象不适合或者不能直接引用另一个对象,使用代理模式起到了中介和保护真实对象的作用,同时提高了扩展性,举个例子吧,好比你买火车票不一定要在火车站买,可以在代售点买,代售点也不一定只卖火车票,还可以扩展业务,卖飞机票,汽车票等。
优缺点?
优点: 1、职责清晰。 2、高扩展性。 3、起到了中介的作用和保护了真实对象的作用。
缺点: 1、由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。 2、实现代理模式需要额外的工作,有些代理模式的实现非常复杂。
应用实例:
1、Windows 里面的快捷方式(Windows桌面上那些五颜六色的图标,快捷方式是Windows提供的一种快速启动程序、打开文件或文件夹的方法。它是应用程序的快速连接。)。
2、买火车票不一定在火车站买,也可以去代售点买。
3、Spring AOP(动态代理)。
和适配器模式和装饰器模式的区别:
1、和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口。
2、和装饰器模式的区别:装饰器模式为了增强功能,而代理模式是为了加以控制。
模式结构
一个是真正的你要访问的对象(目标类),一个是代理对象,真正对象与代理对象实现同一个接口,先访问代理类再访问真正要访问的对象。
代理模式分为静态代理、动态代理。
静态代理 是在程序运行前就事先写好代理类,可以手工编写也可以使用工具生成,缺点是每个业务类都要对应一个代理类,特别不灵活也不方便,于是就有了动态代理。
动态代理 是程序在运行期间动态构建代理对象和动态调用代理方法的一种机制,实现方式有JDK Proxy和CGLib(Code Generation Library)两种。
实例分析
抽象接口:
package Proxy;
/** * @author 佛大java程序员 * @since 1.0.0 */ public interface Image { void display(); }
真实对象:
package Proxy; /** * @author 佛大java程序员 * @since 1.0.0 */ public class RealImage implements Image { private String fileName; public RealImage(String fileName){ this.fileName = fileName; loadFromDisk(fileName); } @Override public void display() { System.out.println("Displaying " + fileName); } private void loadFromDisk(String fileName){ System.out.println("Loading " + fileName); } }
代理对象:
package Proxy; /** * @author 佛大java程序员 * @since 1.0.0 */ public class ProxyImage implements Image{ private RealImage realImage; private String fileName; public ProxyImage(String fileName){ this.fileName = fileName; } @Override public void display() { if(realImage == null){ realImage = new RealImage(fileName); } realImage.display(); } }
客户端(Client):
package Proxy; /** * @author 佛大java程序员 * @since 1.0.0 */ public class Client { public static void main(String[] args) { Image image = new ProxyImage("佛大java程序员.jpg"); // 图像将从磁盘加载 image.display(); System.out.println(""); // 图像不需要从磁盘加载 image.display(); }
运行结果:
常见面试题:
(1)为什么要用代理模式?
参考:
百度百科 -- 代理模式
https://baike.baidu.com/item/%E4%BB%A3%E7%90%86%E6%A8%A1%E5%BC%8F/8374046?fr=aladdin
菜鸟教程 -- 代理模式
https://www.runoob.com/design-pattern/proxy-pattern.html
掘金 -- 3种代理模式-理解Spring Aop
https://juejin.im/post/5cea0180e51d4550bf1ae7db#heading-3
静态代理其实就是事先写好代理类,可以手工编写也可以使用工具生成,但它的缺点是每个业务类都要对应一个代理类,特别不灵活也不方便,于是就有了动态代理。