深究设计模式之-代理模式

代理模式(Proxy Pattern) 是一种结构型设计模式,其目的是通过创建一个代理对象,控制对其他对象的访问。代理对象充当了客户端与目标对象之间的中介,可以在访问目标对象之前或之后执行一些操作,如记录日志、控制访问权限等。

通俗地说,就像我们请一个代理人代表我们做某件事情,代理模式也是通过引入一个代理对象来间接访问目标对象,从而控制和管理对目标对象的访问。

想象我们是非常忙碌的公司老板,每天都有很多会议、电话、文件需要处理。为了能更有效地管理时间,我们雇佣了一位秘书来帮助我们处理一些日常事务。

这位秘书就像是我们的代理,她可以代表我们处理一些事情,比如安排会议、回复邮件、接听电话等。当有人想要和我们预约会议时,他们通常会先联系秘书,而不是直接找我们。秘书在必要时会筛选那些重要的事项,然后将它们交给我们,而我们则可以专注于最重要的工作。并且有些准备工作或者有些收尾工作,秘书也会自己完成,不会来麻烦我们。

在这个例子中,我们就是被代理的对象 ,而秘书就是代理对象。通过秘书这个代理,我们可以更有效地管理我们的时间和工作,而不必自己处理所有的琐事。

主要角色:

  1. 抽象主题(Subject): 定义了目标对象和代理对象共同实现的接口。
  2. 真实主题(Real Subject): 实现了抽象主题接口,是目标对象。
  3. 代理(Proxy): 实现了抽象主题接口,包含了对真实主题的引用,可以在调用真实主题前后执行一些额外的操作。

示例:

举一个简单的图像加载器的例子,真实主题是图像加载器,代理对象可以在加载图像前后记录日志。

java 复制代码
package com.luke.designpatterns.proxyPattern;

// 抽象主题
interface Image {
    void display();
}

// 真实主题
class RealImage implements Image {
    private String filename;

    public RealImage(String filename) {
        this.filename = filename;
        loadImageFromDisk();
    }

    private void loadImageFromDisk() {
        System.out.println("加载图片: " + filename);
    }

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

// 代理
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);
        }
        // 在显示前后可以执行一些额外的操作
        System.out.println("代理准备加载图片: " + filename);
        realImage.display();
        System.out.println("代理加载图片完毕: " + filename);
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        Image image1 = new ProxyImage("图片.jpg");
//        Image image2 = new ProxyImage("图片2.png");
        System.out.println("--------------------");
        // 图像将在调用 display() 时被加载和显示
        image1.display();
//        image2.display();
        System.out.println("--------------------");
        // 由于代理在第一次调用时已经加载过了真实对象,再次调用时直接显示
        image1.display();
    }
}

在这个例子中,Image 是抽象主题接口,RealImage 是真实主题,负责加载和显示图像。ProxyImage 是代理,包含对真实主题的引用,在调用真实主题的 display() 方法前后执行额外的操作,例如记录日志。客户端代码通过代理对象访问真实主题,代理对象在需要时创建和管理真实主题,从而控制对真实主题的访问。代理模式在需要控制对对象访问的场景中非常有用,例如延迟加载、访问控制、日志记录等。

适用场景

代理模式在软件开发中有许多实际可用的场景,以下是其中一些常见的:

  1. 网络请求代理:在应用程序中进行网络请求时,可以使用代理模式来处理网络请求的发送和接收。代理可以负责处理网络连接、数据序列化、错误处理等任务,从而解耦应用程序与网络通信的细节。
  2. 安全代理:在需要控制对敏感资源或操作访问权限时,可以使用安全代理。安全代理可以验证用户的身份和权限,确保只有经过授权的用户才能访问资源或执行操作。
  3. 对象关联代理:当需要管理对象之间的关联关系时,可以使用对象关联代理。代理对象可以在访问目标对象之前或之后执行一些额外的逻辑,如延迟加载、缓存等。
  4. 日志记录代理:在应用程序中加入日志记录代理,可以记录方法调用、参数、返回值等信息,用于调试、监控和审计。日志记录代理可以帮助开发人员追踪和分析应用程序的行为。
  5. 缓存代理:在需要频繁访问资源或执行计算密集型操作时,可以使用缓存代理来提高系统性能。代理可以缓存结果,避免重复计算或查询,从而加快响应速度。
  6. 远程代理:在分布式系统中,客户端可能需要与远程服务器进行通信。远程代理可以隐藏网络通信的细节,使客户端代码更加简洁和易于维护。
  7. 动态代理:使用动态代理可以在运行时动态创建代理对象,而不需要预先定义接口或实现类。这种灵活性使得动态代理特别适用于实现框架、AOP(面向切面编程)等场景。
相关推荐
芯冰乐18 分钟前
综合时如何计算net delay?
后端·fpga开发
希忘auto31 分钟前
Java之线程篇四
java
蓝黑202042 分钟前
Java知识点小结3:内存回收
java·gc
Yz98761 小时前
Hadoop里面MapReduce的序列化与Java序列化比较
java·大数据·jvm·hadoop·分布式·mapreduce·big data
凯哥Java1 小时前
优化批处理流程:自定义BatchProcessorUtils的设计与应用
java·数据库·mysql
njnu@liyong1 小时前
AOP-前置原理-怎么判断和拦截?
java·aop·拦截
末央&1 小时前
【C++】内存管理
java·开发语言·c++
心之语歌2 小时前
设计模式 享元模式(Flyweight Pattern)
java·设计模式·享元模式
MTingle2 小时前
【Java EE】文件IO
java·java-ee
coffee_baby2 小时前
享元模式详解:解锁高效资源管理的终极武器
java·spring boot·mybatis·享元模式