【HeadFirst系列之HeadFirst计划模式】第12天之署理模式:控制对象访问的利器!

[复制链接]
发表于 昨天 22:17 | 显示全部楼层 |阅读模式
署理模式:控制对象访问的利器!

各人好!本日我们来聊聊计划模式中的署理模式(Proxy Pattern)。假如你曾经须要控制对某个对象的访问,大概在访问对象时添加额外的逻辑(如权限查抄、日志日志纪录等),那么署理模式就是你的救星!本文基于《Head First 计划模式》的署理模式章节,通过生动的故事和 Java 代码示例,带你轻松把握署理模式的英华。我们还会探究署理模式在 JDKSpring 等框架中的应用,让你真正明确它的实际代价。


1. 署理模式是什么?

署理模式是一种布局型计划模式,它答应通过一个署理对象来控制对另一个对象的访问。署理模式的焦点头脑是在不改变原始类的情况下,通过引入署理类来加强或控制对原始类的访问
实用场景


  • 须要控制对某个对象的访问(如权限查抄、耽误加载等)。
  • 须要在访问对象时添加额外的逻辑(如日志日志纪录、性能监控监控等)。
  • 须要为长途对象提供当地署理(如长途方法调用 RMI)。

2. 署理模式的实现

故事配景

小明开辟了一个图片查察器体系,体系中有一个 Image 类用于加载和表现图片。由于图片加载是一个耗时的操纵,小明盼望在图片真正表现之前,先表现一个占位符(如加载中…),并在图片加载完成后再表现实际图片。
标题出现

假如直接在 Image 类中实现加载逻辑,会导致图片查察器的性能降落,由于每次加载图片时都须要等候图片加载完成。
办理方案:署理模式

小明决定使用署理模式,通过引入一个署理类 ImageProxy 来控制对 Image 对象的访问。署理类可以在图片加载完成前表现占位符,并在图片加载完成后表现实际图片。

3. 代码实现

1. 界说接口

起首,我们界说一个接口 Image,包罗图片表现的方法。
  1. // 图片接口
  2. interface Image {
  3.     void display();
  4. }
复制代码
2. 实现真实对象

接下来,我们实现真实的图片类 RealImage,用于加载和表现图片。
  1. // 真实图片类
  2. class RealImage implements Image {
  3.     private String filename;
  4.     public RealImage(String filename) {
  5.         this.filename = filename;
  6.         loadFromDisk();
  7.     }
  8.     private void loadFromDisk() {
  9.         System.out.println("Loading image: " + filename);
  10.     }
  11.     @Override
  12.     public void display() {
  13.         System.out.println("Displaying image: " + filename);
  14.     }
  15. }
复制代码
3. 实当署理对象

然后,我们实当署理类 ImageProxy,用于控制对 RealImage 对象的访问。
  1. // 图片代理类
  2. class ImageProxy implements Image {
  3.     private String filename;
  4.     private RealImage realImage;
  5.     public ImageProxy(String filename) {
  6.         this.filename = filename;
  7.     }
  8.     @Override
  9.     public void display() {
  10.         if (realImage == null) {
  11.             realImage = new RealImage(filename); // 延迟加载
  12.         }
  13.         realImage.display();
  14.     }
  15. }
复制代码
4. 客户端代码

末了,我们编写客户端代码来测试署理模式。
  1. public class ImageViewer {
  2.     public static void main(String[] args) {
  3.         Image image = new ImageProxy("photo.jpg");
  4.         // 图片未加载时,代理类可以显示占位符
  5.         System.out.println("Image will be loaded on demand.");
  6.         // 第一次显示图片,触发加载
  7.         image.display(); // 输出: Loading image: photo.jpg, Displaying image: photo.jpg
  8.         // 第二次显示图片,无需重新加载
  9.         image.display(); // 输出: Displaying image: photo.jpg
  10.     }
  11. }
复制代码

4. 署理模式的优缺点

优点


  • 职责清楚:署理类负责控制对真实对象的访问,真实对象只需关注焦点逻辑。
  • 耽误加载:可以通过署理类实现耽误加载,进步体系性能
  • 加强功能:可以在不修改真实对象的情况下,通过署理类添加额外的功能(如权限查抄、日志日志纪录等)。
缺点


  • 增长复杂度:引入署理类会增长体系的复杂度。
  • 性能开销:署理类大概会引入额外的性能开销(如方法调用的间接性)。

5. 署理模式在 JDK 和 Spring 中的应用

1. JDK 中的应用


  • 动态署理:JDK 提供了 java.lang.reflect.Proxy 类,用于创建动态署理对象。动态署理可以在运行时天生署理类,常用于实现 AOP(面向切面编程)。
  • RMI(长途方法调用):JDK 的 RMI 框架使用署理模式来实现长途对象的当地署理。
动态署理示例
  1. import java.lang.reflect.InvocationHandler;
  2. import java.lang.reflect.Method;
  3. import java.lang.reflect.Proxy;
  4. // 接口
  5. interface Greeting {
  6.     void sayHello();
  7. }
  8. // 真实对象
  9. class GreetingImpl implements Greeting {
  10.     @Override
  11.     public void sayHello() {
  12.         System.out.println("Hello, World!");
  13.     }
  14. }
  15. // 动态代理处理器
  16. class LoggingHandler implements InvocationHandler {
  17.     private Object target;
  18.     public LoggingHandler(Object target) {
  19.         this.target = target;
  20.     }
  21.     @Override
  22.     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  23.         System.out.println("Before method: " + method.getName());
  24.         Object result = method.invoke(target, args);
  25.         System.out.println("After method: " + method.getName());
  26.         return result;
  27.     }
  28. }
  29. // 客户端代码
  30. public class DynamicProxyDemo {
  31.     public static void main(String[] args) {
  32.         Greeting realObject = new GreetingImpl();
  33.         Greeting proxy = (Greeting) Proxy.newProxyInstance(
  34.             realObject.getClass().getClassLoader(),
  35.             realObject.getClass().getInterfaces(),
  36.             new LoggingHandler(realObject)
  37.         );
  38.         proxy.sayHello(); // 输出: Before method: sayHello, Hello, World!, After method: sayHello
  39.     }
  40. }
复制代码
2. Spring 中的应用


  • AOP(面向切面编程):Spring 的 AOP 模块使用署理模式来实现切面功能(如日志纪录、事件管理等)。Spring 支持 JDK 动态署理和 CGLIB 署理。
  • 事件管理:Spring 的事件管理器通过署理模式来控制事件的开启、提交和回滚。
Spring AOP 示例
  1. import org.springframework.aop.framework.ProxyFactory;
  2. import org.springframework.aop.support.DefaultPointcutAdvisor;
  3. import org.springframework.aop.support.NameMatchMethodPointcut;
  4. // 接口
  5. interface Service {
  6.     void perform();
  7. }
  8. // 真实对象
  9. class ServiceImpl implements Service {
  10.     @Override
  11.     public void perform() {
  12.         System.out.println("Performing service...");
  13.     }
  14. }
  15. // 切面类
  16. class LoggingAspect {
  17.     public void before() {
  18.         System.out.println("Before method execution.");
  19.     }
  20.     public void after() {
  21.         System.out.println("After method execution.");
  22.     }
  23. }
  24. // 客户端代码
  25. public class SpringAOPDemo {
  26.     public static void main(String[] args) {
  27.         Service realObject = new ServiceImpl();
  28.         ProxyFactory proxyFactory = new ProxyFactory(realObject);
  29.         // 创建切点
  30.         NameMatchMethodPointcut pointcut = new NameMatchMethodPointcut();
  31.         pointcut.addMethodName("perform");
  32.         // 创建切面
  33.         LoggingAspect aspect = new LoggingAspect();
  34.         proxyFactory.addAdvisor(new DefaultPointcutAdvisor(pointcut, (method, args1, target) -> {
  35.             aspect.before();
  36.             Object result = method.invoke(target, args1);
  37.             aspect.after();
  38.             return result;
  39.         }));
  40.         // 获取代理对象
  41.         Service proxy = (Service) proxyFactory.getProxy();
  42.         proxy.perform(); // 输出: Before method execution., Performing service..., After method execution.
  43.     }
  44. }
复制代码

6. 总结

署理模式通过引入署理类来控制对真实对象的访问,从而在不修改原始类的情况下加强或控制其举动。它的焦点上风在于:

  • 职责分离:署理类负责控制访问,真实对象专注于焦点逻辑。
  • 耽误加载:通过署理类实现耽误加载,提升体系性能。
  • 加强功能:通过署理类添加额外功能(如日志纪录、权限查抄等)。
盼望本文能资助你更好地明确署理模式,并在实际项目中机动运用!

互动话题
你在项目中使用过署理模式吗?遇到过哪些风趣的标题?接待在批评区分享你的履历!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
继续阅读请点击广告

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

×
登录参与点评抽奖,加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表