2.7设计模式——Proxy 代理模式(结构型)

意图

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

结构

  1. Proxy保存一个引用使得代理可以访问实体;提供一个与Subject的接口相同的接口,使代理可以用来替代实体;控制实体的存取,并可能负责创建和删除它;其他功能依赖于代理的类型;
    1. Remote Proxy负责对请求及其他参数进行编码,冰箱不同地址空间中的实体发送已编码的请求;
    2. Virtual Proxy可以缓存实体的附加信息,以便延迟对它的访问;
    3. Protection Proxy检查调用者是否具有实现一个请求所必须的访问权限;
  2. Subject定义RealSubject和Proxy的公用接口,这样就可以在任何使用RealSubject的地方都可以使用Proxy。
  3. RealSubject定义Proxy所代表的实体。

适用性

Proxy模式适用于在需要比较通用和复杂的对象指针替代简单指针的时候,常见的情况有:

  • 远程代理(Remote Proxy):为一个对象在不同地址空间提供局部代表。
  • 虚拟代理(Virtual Proxy):根据需要创建开销很大的对象。
  • 保护代理(Protecion Proxy):控制对原始对象的访问,用于对象应该有不同的访问权限的时候。
  • 智能引用(Smart Reference):取代了简单额指针,它在访问对象时执行一些附加操作,典型用途包括:对指向实际对象的引用计数,这样当该对象没有引用时,可以被自动释放;当第一次引用一个持久对象时,将它装入内存;在访问一个实际对象前,检查是否已经锁定了它,以确保其他对象不能改变它。

代码示例

使用虚拟代理模式来设计图像查看器程序。将创建一个虚拟代理类 ImageProxy 和一个真实类 RealImageImageProxy 类将延迟加载 RealImage 对象。

java 复制代码
// 虚拟代理类
public class ImageProxy implements Image {
    private String filename;
    private RealImage realImage;

    public ImageProxy(String filename) {
        this.filename = filename;
    }

    @Override
    public void display() {
        if (realImage == null) {
            realImage = new RealImage(filename);
        }
        realImage.display();
    }
}

// 真实类
public class RealImage implements Image {
    private String filename;

    public RealImage(String filename) {
        this.filename = filename;
        // 加载图像数据
        System.out.println("加载图像:" + filename);
    }

    @Override
    public void display() {
        // 显示图像
        System.out.println("显示图像:" + filename);
    }
}

// 测试代码
public class Main {
    public static void main(String[] args) {
        Image image1 = new ImageProxy("image1.jpg");
        Image image2 = new ImageProxy("image2.jpg");

        image1.display(); // 加载图像1
        image2.display(); // 加载图像2
        image1.display(); // 不再加载图像1
    }
}

代码设计注释

  • ImageProxy 类是一个虚拟代理类,它实现了 Image 接口。
  • ImageProxy 类有一个构造函数,它接受图像文件名作为参数。
  • ImageProxy 类有一个 display() 方法,它负责显示图像。如果 realImage 对象为空,则创建一个新的 RealImage 对象并加载图像数据。否则,直接调用 realImage.display() 方法。
  • RealImage 类是一个真实类,它也实现了 Image 接口。
  • RealImage 类有一个构造函数,它接受图像文件名作为参数。
  • RealImage 类有一个 display() 方法,它负责显示图像。
  • Main 类中,创建了两个 ImageProxy 对象,并调用了它们的 display() 方法。第一次调用 image1.display() 时,会加载图像1。第一次调用 image2.display() 时,会加载图像2。第二次调用 image1.display() 时,不会再加载图像1,因为 realImage 对象已经存在
相关推荐
呼啦啦啦啦啦啦啦啦6 小时前
常见的排序算法
java·算法·排序算法
anlogic7 小时前
Java基础 8.18
java·开发语言
练习时长一年7 小时前
AopAutoConfiguration源码阅读
java·spring boot·intellij-idea
源码宝9 小时前
【智慧工地源码】智慧工地云平台系统,涵盖安全、质量、环境、人员和设备五大管理模块,实现实时监控、智能预警和数据分析。
java·大数据·spring cloud·数据分析·源码·智慧工地·云平台
David爱编程9 小时前
面试必问!线程生命周期与状态转换详解
java·后端
LKAI.10 小时前
传统方式部署(RuoYi-Cloud)微服务
java·linux·前端·后端·微服务·node.js·ruoyi
HeyZoeHey10 小时前
Mybatis执行sql流程(一)
java·sql·mybatis
2301_7930868710 小时前
SpringCloud 07 微服务网关
java·spring cloud·微服务
柳贯一(逆流河版)11 小时前
Spring 三级缓存:破解循环依赖的底层密码
java·spring·缓存·bean的循环依赖
该用户已不存在13 小时前
OpenJDK、Temurin、GraalVM...到底该装哪个?
java·后端