java设计模式(十二)代理模式

news2024/12/22 18:00:03

目录

  • 定义
  • 模式结构
  • 角色职责
  • 代码实现
    • 静态代理
    • 动态代理
    • jdk动态代理
    • cglib代理
  • 适用场景
  • 优缺点

定义

代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。说简单点,代理模式就是设置一个中间代理来控制访问原目标对象,以达到增强原对象的功能和简化访问方式。

模式结构

在这里插入图片描述

角色职责

1.抽象角色:通过接口或抽象类声明真实角色实现的业务方法。
2.代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。
3.真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。

代码实现

代理模式属于结构性模式,有静态代理和动态代理。

静态代理是由程序员创建或工具生成代理类的源码,再编译代理类。所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。
动态代理是在实现阶段不用关心代理类,而在运行阶段才指定哪一个对象。

静态代理

抽象角色

public interface Subject {
    void Request();
}

代理角色

public class Proxy implements Subject {
    private RealSubject realSubject;
    @Override
    public void Request() {
        if (realSubject == null) {
            realSubject = new RealSubject();
        }
        preRequest();
        realSubject.Request();
        postRequest();
    }
    public void preRequest() {
        System.out.println("访问真实主题之前的预处理");
    }
    public void postRequest() {
        System.out.println("访问真实主题之后的后续处理");
    }
}

真实角色

public class RealSubject implements Subject {
    @Override
    public void Request() {
        System.out.println("访问真实主题方法");
    }
}

动态代理

jdk动态代理

抽象角色

public interface Animal {
    void eat();
    void sleep();
}

代理角色

public class JDKDynamicProxy implements InvocationHandler {
    private Object bean;
    public JDKDynamicProxy(Object bean) {
        this.bean=bean;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        String methodname = method.getName();
        if (methodname.equals("eat")){
            System.out.println("吃饭了~~~");
        }else if(methodname.equals("sleep")){
            System.out.println("睡觉了~~~");
        }
        return method.invoke(bean,args);
    }
}

真实角色

public class Cat implements Animal {
    private String name;
    public Cat() {
    }
    public Cat(String name) {
        this.name = name;
    }
    @Override
    public void eat() {
        System.out.println("喵喵"+name+"早晨吃饭了");
    }
    @Override
    public void sleep() {
        System.out.println("喵喵"+name+"晚上睡觉啦");
    }
}

测试类

public class TestJDKDynamicProxy {
    public static void main(String[] args) {
        JDKDynamicProxy  proxy = new JDKDynamicProxy(new Cat("喵喵"));
        Animal cat = (Animal) Proxy.newProxyInstance(proxy.getClass().getClassLoader(), new Class[]{Animal.class}, proxy);
        cat.eat();
        cat.sleep();
    }
}

cglib代理

代理角色

public class CglibProxy implements MethodInterceptor {
    private Enhancer enhancer=new Enhancer();
    private Object bean;

    public CglibProxy(Object bean) {
        this.bean = bean;
    }

    public Object getProxy(){
        //设置需要创建子类的类
        enhancer.setSuperclass(bean.getClass());
        enhancer.setCallback(this);
        return enhancer.create();

    }
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        String methodName = method.getName();
        if (methodName.equals("eat")){
            System.out.println("吃饭了~~~");
        }else if(methodName.equals("sleep")){
            System.out.println("睡觉了~~~");
        }
        return method.invoke(bean,objects);
    }
}

测试类

public class TestCglibProxy {
    public static void main(String[] args) {
        CglibProxy proxy = new CglibProxy(new Cat("喵喵"));
        Cat cat = (Cat) proxy.getProxy();
        cat.wakeup();
        cat.sleep();
    }
}

适用场景

代理模式可以在代理对象将请求转发给真实对象之前及之后可以执行操作,这使得代理模式应用场景非常广泛,如权限校验、日志记录,以及缓存等等,以及把一些重复代码使用代理模式进行重构提取。

优缺点

优点:
1.代理模式能将代理对象与真实被调用的目标对象隔离
2.一定程度上降低了系统的耦合度,扩展性好
3.可以起到保护目标对象的作用
4.可以对目标对象的功能增强
缺点:
1.代理模式会造成系统设计中类的数量增加
2.在客户端与目标对象之间增加一个代理对象,会造成请求处理速度变慢
3.增加了系统的复杂度
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/617578.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

高度平衡二叉搜索树(AVLTree)(插入与旋转)

目录 简介 AVL的结点类 平衡因子的性质 AVL树的插入 更新平衡因子的接口(ChangeBf) 第一种情况:插入后父节点的平衡因子为0 第二种情况:更新后父节点的平衡因子的绝对值为1 第三种情况:更新后父节点的平衡因子的绝对值为2 旋转接口(…

cam_lidar_calibration代码详解(一)采样优化部分

目录 一、launch启动程序 1.1 run_optimiser.launch标定优化程序 1.2 assess_results.launch重投影误差评估程序 二、主要代码 2.1 feature_extraction_node.cpp文件 2.2 feature_extractor.cpp文件 2.2.1 FeatureExtractor::callback_camerainfo函数 2.2.2 serviceCB函…

QT快速操作Excel的实现介绍及操作类封装

QT中操作Excel还是比较简单的,Qt提供了QAxObject,包装COM组件的类,通过COM通过COM操作使用QAxObject类,使用此类,需要在pro文件中添加"QT   axcontainer "。 基本流程介绍 QAxObject: QAxObj…

SAP从入门到放弃系列之pMRP

最近学习pMRP,查了很多博客,机翻一篇内容非常详细的文章,感谢大佬: 原文地址: pMRP–Predictive Material and Resource Planning in SAP S/4HANA : Step by Step execution pMRP https://blogs.sap.com/2020/04/14/p…

机器学习【线性回归】

机器学习【线性回归】 回归预测的结果是离散型变量,身高和年龄 损失函数:SSE(误差平方和),RSS(残差平方和),误差越大越差 最小二乘法:通过最小化真实值和预测值之间的…

大数据:sparkSQL,历史,DataSet,DataFrame,sparkSession

大数据:sparkSQL 2022找工作是学历、能力和运气的超强结合体,遇到寒冬,大厂不招人,可能很多算法学生都得去找开发,测开 测开的话,你就得学数据库,sql,oracle,尤其sql要学…

第十章:创建和管理表

第十章:创建和管理表 10.1:基础知识 一条数据存储的过程 ​ 存储数据是处理数据的第一步。只有正确地把数据存储起来,我们才能进行有效的处理和分析。否则,只能是一团乱麻,无从下手。 ​ 在MySQL中,一个完…

使用模板方法模式封装协议消息

目录 整体框架 模板方法介绍 关于本案例设计 c impl惯用法 cimpl惯用法好处 此案例impl惯用法的设计 关于序列化和反序列化 序列化和反序列化 本项目使用介绍 谷歌测试 谷歌测试环境 谷歌测试用例 完整源码地址 概述 本文介绍了从 设计模式之模板方法模式协议消…

面对CPU狂飙时的5步解决方案

现在企业对后端开发的要求越来越高,不仅要求我们会写代码,还要我们能够进行部署和运维! 项目上线并运行一段时间后,可能会发现部署所在的Linux服务器CPU占用过高,该如何排查解决? 本文用5步带你搞定线上CPU…

操作系统-进程和线程-同步、互斥、死锁

目录 一、同步互斥 二、互斥的实现方法 2.1软件实现 2.1.1单标志法 2.1.2双标志先检查 2.1.3双标志后检查 2.1.4Petersons算法 2.2硬件实现 2.2.1 TestAndSet指令 2.2.2 Swap指令 三、信号量机制 3.1整形变量 3.2 记录型变量 3.3用信号量实现进程互斥、同步、前驱关系…

Sui与F1甲骨文红牛车队达成合作

在近期达成的一项为期多年的合作协议中,甲骨文红牛车队将利用Sui网络开发,为粉丝带来全新的数字化体验。 甲骨文红牛车队的粉丝将很快在Sui网络上体验到他们最爱的一级方程式车队带来的激情。最近几个赛季一直统治着F1赛场的甲骨文红牛车队,与…

代码随想录算法训练营第五十三天 | 力扣 1143.最长公共子序列, 1035.不相交的线, 53. 最大子序和

1143.最长公共子序列 题目 1143. 最长公共子序列 给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0 。 一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符…

2022年值得关注的7个主要SD-WAN趋势

随着SD-WAN技术在2022年继续发展成熟,该技术在集成远程访问、自动化和多云连接方面的支持有望得到更多的改进。 软件定义WAN仍然是增强用户体验(UX),提高安全性,以及提供与基于云计算的应用程序的连接的一项关键技术。 随着SD-WAN的成熟&…

java设计模式之:原型模式

在我们的生活中,有很多例子,都是用到了原型模式,例如:我们去配钥匙的时候,肯定先要有一个原配钥匙才可以去配钥匙;《西游记》中孙悟空可以用猴毛根据自己的形象,复制(又称“克隆”或…

时间序列预测 | Matlab基于北方苍鹰算法优化随机森林(NGO-RF)与随机森林(RF)的时间序列预测对比

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 时间序列预测 | Matlab基于北方苍鹰算法优化随机森林(NGO-RF)与随机森林(RF)的时间序列预测对比 评价指标包括:MAE、RMSE和R2等,代码质量极高,方便学习和替换数据。要求2018版本及以上。 部分源码 %-----------…

【Apache-Flink零基础入门】「入门到精通系列」手把手+零基础带你玩转大数据流式处理引擎Flink(基础概念解析)

手把手零基础带你玩转大数据流式处理引擎Flink 前言介绍Apache Flink 的定义、架构及原理Flink应用服务Streams有限数据流和无限数据流的区别 StateTimeAPI Flink架构体系 Flink操作处理Flink 的应用场景Flink 的应用场景:Data Pipeline实时数仓搜索引擎推荐 Flink …

华为诺亚 VanillaNet

文章标题:《VanillaNet: the Power of Minimalism in Deep Learning》 文章地址:https://arxiv.org/abs/2305.12972 github地址:https://github.com/huawei-noah/VanillaNet 华为诺亚方舟实验室和悉尼大学,2023年5月代码刚开源的…

基于HAL库的STM32的单定时器的多路输入捕获测量脉冲频率(外部时钟实现)

目录 写在前面 一般的做法(定时器单通道输入捕获) 以外部时钟的方式(高低频都适用) 测试效果 写在前面 STM32的定时器本身有输入捕获的功能。可选择双端捕获,上升沿捕获或者是下降沿捕获。对应捕获频率来说,连续捕获上升沿或下降沿的时间间隔就是其脉…

手把手教你F103工程文件的创建并且通过protesu仿真验证创建工程文件的正确性(低成本)

目录 一、新建工程文件夹 二、新建一个工程框架 三、添加文件 四、仿真验证 五、仿真调试中遇到的问题并解决 一、新建工程文件夹 新建工程文件夹分为 2 个步骤:1,新建工程文件夹;2,拷贝工程相关文件。 1.新建工程文件 首先…

【04】STM32·HAL库开发-MDK5使用技巧 |文本美化 | 代码编辑技巧 | 查找与替换技巧 | 编译问题定位 | 窗口视图初始化

目录 1.文本美化(熟悉)1.1编辑器设置1.2字体和颜色设置1.3用户关键字设置1.4代码提示&语法检测1.5global.prop文件妙用 2.代码编辑技巧(熟悉)2.1Tab键的妙用2.2快速定位函数或变量被定义的地方2.3快速注释&快速取消注释 3…