首页 > 其他分享 >2021-12-29-md1

2021-12-29-md1

时间:2024-08-23 11:03:53浏览次数:3  
标签:ComplexCalculate execute 12 代理 long System 2021 md1 result

代码:https://gitee.com/Aes_yt/design-pattern

代理模式

代理模式需要给某对象提供一个代理来访问该对象。是客户端和目标对象之间的一个媒介。

代理模式主要包括三种角色
  • 抽象主题:接口或抽象类,有着业务方法,可以让真实主题和代理对象来实现。
  • 真实主题:实现了抽象主题的方法,是代理类所代理的真实对象。
  • 代理类:提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。

代理模式又分为静态代理和动态代理,静态代理是程序运行前,.class文件已经存在,而动态代理则是利用反射原理,动态创建类。

例子

我们如果有一个计算类,它在方法中进行复杂计算,然后我们要在计算前后进行日志记录,并统计计算的耗时,这时可以用代理模式来实现。

1. 静态代理

image-20211229000217567

Calculate 抽象主题:

public interface Calculate {
    long execute(int time);
}

ComplexCalculate 真实主题:

public class ComplexCalculate implements Calculate {
    /**
     * 在方法里面进行计算,要用到time参数
     */
    @Override
    public long execute(int time) {
        System.out.println("调用了 ComplexCalculate 类中的 execute 方法。参数是" + time);
        long i = 1;
        for (int j = 0; j < time; j++) {
            i += 5;
        }
        return i;
    }
}

ProxyCalculate 代理类:

public class ProxyCalculate implements Calculate {
    private ComplexCalculate calculate = new ComplexCalculate();

    @Override
    public long execute(int time) {
        long start = System.currentTimeMillis();
        System.out.println("开始执行");
        long result = calculate.execute(time);
        long end = System.currentTimeMillis();
        System.out.println("结束执行, 耗时:" + (end - start) + " ms");
        return result;
    }
}

测试:

    @Test
    void execute() {
        ProxyCalculate calculate = new ProxyCalculate();
        long result = calculate.execute(1000000);
        System.out.println("result:" + result);
    }

输出:

开始执行
调用了 ComplexCalculate 类中的 execute 方法。参数是1000000
结束执行, 耗时:1 ms
result:5000001

分析:

在ProxyCalculate 代理类中,实现了抽象接口,并且声明了ComplexCalculate真实主题类属性,而实际执行execute方法的则是ComplexCalculate的实例对象。从而实现了通过代理类去访问真实对象,并且在执行方法前可以编写自己的逻辑。

2. 动态代理 jdk

我们用jdk自带的Proxy类来实现动态代理,抽象主题和真实主题不变,和上面的静态代理一样,不同的只是ProxyCalculate 代理类我们改成代理工厂,生成代理对象的实例。

image-20211229000137999

ProxyFactory :

public class ProxyFactory {
    private ComplexCalculate calculate = new ComplexCalculate();

    /**
     * Proxy.newProxyInstance 三个参数:
     * ClassLoader loader:类加载器
     * Class<?>[] interfaces:代理类接口字节码
     * InvocationHandler h:代理对象的调用程序,此处用lambda实现,有三个参数
     * Object proxy: 代理对象
     * Method method : 调用方法的method对象
     * Object[] args : 调用方法的参数
     */
    public Calculate getCalculateObj() {
        return (Calculate) Proxy.newProxyInstance(
                calculate.getClass().getClassLoader(),
                calculate.getClass().getInterfaces(),
                (proxy, method, args) -> {
                    long start = System.currentTimeMillis();
                    System.out.println("开始执行");
                    // ==== 实际执行的就是这一行,其他的都是额外的自定义逻辑 ====
                    long result = (long) method.invoke(calculate, args);
                    // ==== ======================================= ====
                    long end = System.currentTimeMillis();
                    System.out.println("结束执行, 耗时:" + (end - start) + " ms");
                    return result;
                });
    }
}

测试:

@Test
void execute() {
    ProxyFactory factory = new ProxyFactory();
    long result = factory.getCalculateObj().execute(1000000);
    System.out.println("result:" + result);
}

输出:

开始执行
调用了 ComplexCalculate 类中的 execute 方法。参数是1000000
结束执行, 耗时:1 ms
result:5000001

注意:

被代理的真实对象是需要实现接口才可以用Proxy进行代理的,如果类没有实现接口的话,可以引入cglib包进行代理。

优缺点

代理模式的优点有:

  • 可以对目标对象的功能进行拓展,比如上边例子上的日志打印等,

  • 代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用

代理模式的缺点有:

  • 增加系统的复杂性
  • 在目标对象之前又增加了代理对象,会使请求的处理速度变慢

标签:ComplexCalculate,execute,12,代理,long,System,2021,md1,result
From: https://www.cnblogs.com/Aeons/p/18375612

相关文章

  • CNN-BiLSTM-Attention(12种算法优化CNN-BiLSTM-Attention多输入单输出)
     12种算法优化CNN-BiLSTM-Attention模型预测的代码。其中Attention模型可以改为单头或者多头,在代码中就是改个数字而已。代码注释已写好如何更改。12种算法优化CNN-BiLSTM-Attention多特征输入单步预测代码获取戳此处代码获取戳此处代码获取戳此处主要功能为:采用12种......
  • 基于 Python 3.12.4 和 PySide 6 的 假用户操作系统【0-0】虚拟终端框架
    基本目标实现工作目录的切换;实现非退出命令下的无限循环;到目前为止还不能实现的功能动态导入py文件中的模块缺少组件定义虚拟进程类command.pyfromctypesimportwindllfromPySide6.QtWidgetsimportQWidgetfromsysimportexitassys_exitfromosimportpath......
  • HTC 10 刷系统 LineageOS 19.1 Android 12
    解锁手机解锁会导致数据全部清除,注意保存Bootloader解锁,S-ON可以不用解锁(好像可以绕过解锁安装twrp,暂时没尝试)HTC官方UnlockBootloaderHTCDesire20pro可以不通过官方网站解锁adbrebootbootloader#进入bootloadersudofastbootflashingunlock#选择UNLOC......
  • 手机轰炸机 短信轰炸 可匣 二90二1243交流
    使用fiddler抓包获取到了100+个发送短信验证的接口使用自己手机试了一下速度非常快。因为是同时迸发,所以导致手机短信量一瞬间到了100+但是会导致一个问题,就是无感知情况于是调整接口请求方式,设置异步请求,间隔3s钟,这次以后会达到一个比较好的效果没办法上传视频只能看......
  • oem 软件更新 p9348486_112000_Generic,zip
    [oracle@prdb19oemtmp]$emclilogin-username=sysmanEnterpassword:Loginsuccessful[oracle@prdb19oemtmp]$emcliimport_update_catalog-file=p9348486_112000_Generic.zip-omslocalUnabletoreadthefilep9348486_112000_Generic.zip.Verifythefilep......
  • 题解:P9041 [PA2021] Fiolki 2
    \(\text{Link}\)题意给定一个\(n\)个点\(m\)条边的DAG,定义\(f(l,r)\)表示最多选取多少条不相交路径\((s_i,t_i)\)满足\(s_i\in[1,k],t_i\in[l,r]\),其中不能有任意一点同时在两条选出的路径上。对\(\forallx\in[0,k)\)求出有多少\([l,r]\sube(k,n]\)使得\(f(l,r)......
  • java版本12计算2000年1月到2023年6月相差几年
     JDK12版本importjava.time.YearMonth;importjava.time.temporal.ChronoUnit;publicclassYearsBetweenDates{publicstaticvoidmain(String[]args){YearMonthstartYearMonth=YearMonth.of(2000,1);YearMonthendYearMonth=YearMon......
  • 呼死你 手机轰炸机 (29021243
    基于短信轰炸机原理研究并实现之后又研究起了电话轰炸机实现原理其实大同小异,最终的区别的用户在进行短信发送并未收到短信的情况下【产生的原因有网络信号原因、用户手机自动屏蔽原因】可以利用第三方平台提供的语音验证码进行发送这种情况也是通过fiddler进行抓包处理......
  • 2024年关于短信轰炸机原理研究并实现的流程 (290021243
    偶然看到gitHub上面有短信轰炸机源码,于是产生了研究的想法。经过研究源码发现是通过抓包进行第三方网站抓包并且收集,最终进行post/get请求。携带header和token进行第三方网站模拟请求。于是在mac上面下载了fiddler进行代理配置开放了本机ip下的8888商品,用手机同时访问本机ip的......
  • OBS直播抠绿插件(Matting123)
    一、产品概述OBS直播抠绿插件(Matting123)是使用绿幕、蓝幕进行抠像的虚拟直播软件,本软件需要配合OBS30.0.0或以上版本进行使用。Matting123采用自研抠图算法,该算法已达到影视级别效果,能非常真实抠出半透明物体,不会出现溢色等问题;精确的边缘检测与边缘过渡能力,非常细腻抠出一根根......