设计模式之代理模式

JS设计模式之代理模式 Star这个类就是明星,StarProxy这个类就是明星经纪人,假如我们是商家,现在我们想请这个明星来参加我们的活动,我们开始和经纪人谈价格,talk出价1w,此时经纪人会做一个判断,如果价格大于等于1w,这个活动就比较适合,可以参加,代理就会去通知明星演出,如果小于1w的话,就不会,这个就是简单的代理模式,我们要访问明星,需要经过经纪人(也就是代理),才能去访问。其实就是给一个对象提供一个代理,如果要访问这个对象必须经过这个代理,先说,这个模式的优点是什么。 阅读详情

本文主要给大家介绍代理模式的定义,用途以及如何实现代理。“代理”一词,相信大家在日常生活中也是经常听到的吧,例如:某个人有多套房子,希望链家帮他出租或者销售出去。又或者某个大明星不想参演某个电视剧,助理帮忙拒绝。这时链家和助理其实就充当的是代理的作用。

定义与特点

给某一个对象提供一个代理对象,并由代理对象控制对原对象的访问。通俗来讲代理对象就是代替真实对象与其它对象进行交互,由代理对象来调用真实对象进行处理。

在日常中,我们很多时候也会使用到代理模式,不一定是在框架中使用,其它地方也会使用到。例如:某个复杂而且代码老旧的项目,为了使它正常的运行,太多的时候,我们都不敢直接修改源码,如果上文依赖不是特别强的情况下,就可以使用代理模式动态扩展,依照项目情况决定。

使用代理模式有很多的好处,总结三点:1.职责清晰。代理对象代替真实对象与其它对象交互,真实对象只需要关注自己的业务逻辑。2.扩展性强。代理对象可以在原对象的实现上增添额外的内容,而不需要修改原有对象。这里是典型的“对扩展开放,对修改关闭”原则。3.保护作用。代理对象能够很好的隐藏真实对象的实现内容。

既然存在优点,那么也有缺点,例如:1.额外的开销。本来之前我们访问一个对象直接调用该对象就可以完成任务,现在加上一层代理,需要额外的代码量,增加复杂度。2.可维护性降低。过多的使用代理模式,可能导致系统中相似的类增多,不利于维护。

分类

从实现方式来讲,代理模式可以分为两大类:静态代理和动态代理。动态代理又分为JDK动态代理和CGLIB动态代理。其中静态代理和JDK动态代理都是针对接口编程,CGLIB动态代理针对具体类。大家应该都比较熟悉Spring吧,其中SpringAop就采用代理模式,当我们的真实对象使用接口就使用JDK动态代理,若使用具体类就采用CGLIB动态代理。下面我们来具体介绍一下这三种方式的实现。

静态代理

静态代理的实现,需要三种对象:抽象对象(真实对象的接口),真实对象(实现抽象对象),代理对象(实现抽象对象)。实现如下:

//共同的接口:StaticProxyInterface
public interface StaticProxyInterface {
    void save();
}
//真实对象
class RealObject implements StaticProxyInterface {

    @Override
    public void save() {
        System.out.println("------保存数据----------");
    }
}
//代理对象
class ProxyObject implements StaticProxyInterface {
    //真实对象
    private StaticProxyInterface realObject;

    public ProxyObject(StaticProxyInterface realObject) {
        this.realObject = realObject;
    }

    @Override
    public void save() {
        System.out.println("保存开始时间:" + System.currentTimeMillis());
        this.realObject.save();
        System.out.println("保存结束时间:" + System.currentTimeMillis());

    }
}

测试:

StaticProxyInterface realObject = new RealObject();
ProxyObject proxyObject = new ProxyObject(realObject);
proxyObject.save();

从上述实现可以发现,在实现静态代理时,真实对象与代理对象都需要实现同一接口,另外需要使用组合的方式将真实对象添加到代理对象中。这样实现的方式有一个很大的优点,代理对象可以代理实现该接口的所有子类并且在原有的基础上扩展功能。但是,这样实现也有很大的缺点,如果接口增加方法,那么代理类必须也实现相同的方法,这样系统则会出现许多类似的对象,不易于维护。所以静态代理在日常项目中使用相对较少。

代理模式的重点就在于动态代理,所以接下来的两种实现方式才是我们关注的重点。

JDK动态代理

实现JDK动态代理,我们需要创建接口,真实对象,代理对象。其中接口,真实对象我们还是使用上述静态代理代码中的内容,代理对象的创建如下:

class ProxyObject {
    //真实对象
    private StaticProxyInterface realObject;

    public ProxyObject(StaticProxyInterface realObject) {
        this.realObject = realObject;
    }

    public Object newProxyInstance() {
        return Proxy.newProxyInstance(realObject.getClass().getClassLoader(), realObject.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("保存开始时间:" + System.currentTimeMillis());
                //利用反射执行目标对象的方法并返回代理对象
                Object invoke = method.invoke(realObject, args);
                System.out.println("保存结束时间:" + System.currentTimeMillis());
                return invoke;
            }
        });
    }
}

JDK动态代理创建代理对象不需要实现同一接口,另外代理对象的创建我们需要依赖java.lang.reflect.Proxy类来进行,该类有一个特别重要的方法:

Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h);
  • ClassLoader loader:指定当前目标对象的类加载器。
  • Class<?>[] interfaces:指定当前目标对象实现的接口的类型。
  • InvocationHandler h:事件处理,执行目标对象的方法时,会触发事件处理器的invoke方法并返回代理对象,我们的逻辑都是在该方法中实现。

使用JDK动态代理,可以在运行时动态的为StaticProxyInterface的子类创建代理对象,扩展性强。在这里,我们的接口只有一个方法save(),假设现在该接口有多个方法,多个方法都需要在原有的基础上扩展,这个时候可以在invoke方法中做如下判断,伪代码:

String name=method.getName();
if("".equals(name)){
    //TODO 
}else if("".equals(name)){
    //TODO
}else{
    //TODO
}

JDK动态代理依赖接口,底层采用反射机制调用目标对象方法。

CGLIB动态代理

CGLIB动态代理与JDK动态代理最大的区别在于,前者依赖具体类,后者依赖接口。要想使用CGLIB动态代理,我们必须引入CGLIB的依赖包,例如:

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.2.10</version>
</dependency>

示例如下:

//目标对象
public class Shopping {

    public void shop() {
        System.out.println("-------我要买买买-------");
    }
}

//实现MethodInterceptor 对目标对象进行拦截
class ProxyShopping implements MethodInterceptor {

    private Object realObject;

    public ProxyShopping(Object realObject) {
        this.realObject = realObject;
    }
    //创建代理对象
    public Object newProxyInstance() {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(Shopping.class);//设置父类,也就是继承Shopping
        enhancer.setCallback(this);//设置回调,也就是对目标对象进行拦截
        return enhancer.create();//动态生成字节码,创建代理对象
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("-------我要带信用卡---------");
        Object invoke = method.invoke(realObject, objects);
        System.out.println("-------信用卡刷爆了---------");
        return invoke;
    }
}

测试:

Shopping shopping = new Shopping();
Shopping proxyInstance= (Shopping)new ProxyShopping(shopping).newProxyInstance();
proxyInstance.shop();

使用CGLIB动态代理,不需要有目标接口,有具体的实现类就可以,但是目标类中的static以及final方法是不能得到代理的。CGLIB动态代理采用的是ASM(字节码编辑类库)动态生成字节码技术实现,JDK动态代理采用的是反射增强目标对象的功能。关于这两种方式,并不能强调某种代理方式的性能更加好,只能说在相应的情形下采用相应的方式,就好比与Spring Aop中,针对bean中有接口就采用JDK动态代理,只有具体实现类的就采用CGLIB动态代理,所以我们不必太去纠结两者的性能,合理使用即可。

总结

代理模式,在日常开发中,都是极其常见的。常常分为两种类型:静态代理和动态代理(JDK动态代理、CGLIB动态代理)。使用代理模式,我们可以在不修改原有类的情况下,扩展其功能,完全符合开闭原则;另外目标对象只需要关注自己的业务逻辑,符合单一职责原则。如何选择代理模式,大家可以根据目前项目情形,合理的选择。在Spring Aop中,利用代理模式处理日志、异常、发送邮件、短信,是很常见的业务。以上内容属于个人的意见,若有不对的地方,望大家指点。

 

 

数字太大放不下,高精度来补,如何放下超大数字,以及进制转换,高精度真的超好玩。 洛谷1009,1015 想必大家都遇到过数字大小超过int类型范围的情况,是不是碰到int放不下的数字自然就会想到,long int,long long int,甚至unsigned long long int呢。但是有一些出题者就很可恶,偏要出一些连unsigned long long int也放不下的算法题,应对这些问题时,我们是否有相应的应对方法呢?答案是:当然有,高精度就是一种应对这种问题时很好的解决办法。相信你在看完这篇文章后能对高精度有着更深更好的理解。我会循序渐进的来讲,这样大家也更容易听懂。 阅读详情

相关推荐

利用mininet模拟SDN架构并进行DDoS攻击与防御模拟(Ryu+mininet+sflow+postman)

1、知识概述 (1)软件定义网络: (2)mininet: Mininet是一个强大的网络仿真平台,通过这个平台,我们可以很方便的模拟真实环境中的网络操作与架构。特别是SDN,在真实网络中进行相关的网络实验有一定难度,自然需要一个仿真平台可以学习这种新型的网络架构,而Mininet就应运而生,承担了这个光荣而艰巨的使命。Mininet自带交换机(switchs)、主机(hosts)、控制器(controllers),同时,在mininet上可以安装OpenvSwitch、多种控制器(NOX\POX

北风 1万+

设计模式之 代理模式

代理模式替原对象进行一些操作,比如我们在租房子的时候回去找中介,打官司我们需要请律师,因为律师在法律方面有专长,做饭需要找厨师! 还拿厨师和理发师的例子吧! 一个理发师不会做饭,一个厨子会做饭,他们都实现一个叫做Person的接口,一个理发师想做饭的话,必须请一个厨子帮忙! 二话不说上代码! public interface Person {       public

xx_dd的博客 347

华为Atlas 300I推理卡驱动安装避坑指南:不同安装方式的选择与优化

本文详细解析华为Atlas 300I推理卡驱动安装的三种主流方式(.run、.rpm和源码编译),提供关键环境检查步骤、安装流程优化建议及常见问题解决方案,帮助开发者高效完成芯片推理卡部署并规避典型安装陷阱。

q9w8e7r6t5的博客 433

使用代理设计模式完成下面的功能一个会烧扬州炒饭的普通厨子要拍电影一个会 红烧肉的大厨子要拍电影一个会 糖醋排骨的阿姨要拍电影。

【代码】使用代理设计模式完成下面的功能一个会烧扬州炒饭的普通厨子要拍电影一个会 红烧肉的大厨子要拍电影一个会 糖醋排骨的阿姨要拍电影。

qq_47348990的博客 367

【TI毫米波雷达】IWR6843AOPEVM-G与DCA1000EVM实战:从硬件连接到数据流解析

本文详细解析了TI毫米波雷达开发套件IWR6843AOPEVM-G与DCA1000EVM的硬件连接、模式配置及数据流处理全流程。针对官方手册中的常见配置错误,提供了避坑指南和实测验证的正确设置方法,包括开关配置、网络参数等关键步骤。通过mmWave Studio软件配置雷达参数,并深入解析数据采集与处理流程,帮助开发者高效实现毫米波雷达应用开发。

weixin_30653023的博客 368

设计模式 之 代理模式 Proxy

代理模式Proxy指为其他对象提供一种代理,以控制对这个对象的访问。 我的理解是代理模式是可以在不修改被代理对象的基础上,通过扩展代理类,进行一些功能的附加与增强,有效防止目标对象的直接访问。

cfa3288的博客 330

HyperMesh二次开发实战:自动化Comp与材料属性批量绑定

本文详细介绍了HyperMesh二次开发中自动化Comp与材料属性批量绑定的实战技巧。通过TCL脚本实现批量创建属性卡、智能材料分配和异常处理,大幅提升前处理效率,适用于汽车、航空航天等领域的复杂模型处理。

weixin_29214691的博客 691

「设计模式(五) - 代理模式」

「设计模式(五) - 代理模式」 一、处处可见的“代理” “代理”在平常生活司空见惯,点外卖,租房子找中介,买飞机票等等。基本上用手机就能完成,也就是不直接接触到对象而通过中介的方式达成自己的需求,它和装饰器在实现上是有点相似的,容易混淆。就目前的项目当中其实没用到代理模式,但还是有必要了解这种结构型模式。 二、代理模式 Proxy 通俗的讲,出于某种原因不能够直接访问目标对象,如目标对象是受保护的内容、远程内容、权限问题等等。需借助代理对象作为调用者与目标对象的中介来操作目标对象的一种结构型设计模式Pr

我有一壶酒,足以慰风尘 494

从零到一:手把手教你用STM32F103C8T6打造个人专属开发板(附立创EDA工程与源码)

本文详细介绍了如何使用STM32F103C8T6微控制器从零开始设计和制作个人专属开发板。内容涵盖硬件选型、原理图设计、PCB布局、功能验证等全流程,并提供了立创EDA工程文件和源码,帮助开发者深入理解STM32开发板的硬件架构与设计要点。

weixin_26802933的博客 286

病理WSI配准库valis教程

病理WSI配准库valis教程

azrealq的博客 2598

代理设计模式

一、概述 代理模式是Java常见的设计模式之一。所谓代理模式是指客户端并不直接调用实际的对象,而是通过调用代理,来间接的调用实际的对象。 举例:购买保险,不直接购买而是通过代理人购买 ​ 购买火车票,自己不去窗口、12306购买 通过黄牛/美团 购买 为什么要采用这种间接的形式来调用对象呢? 1.因为客户端不想直接访问实际的对象,或者访问实际的对象存在困难,因此通过一个代理对象来完成间接的访问。 2.不改变原程序代码的前提下,对功能进行扩充。通过代理模式,我们可以很方便的给代码添加日志

xue_yun_xiang的博客 573

电子科技大学计算机预推免(最终去向)

电子科技大学,预推免报名时必须要有一封本校老师写的推荐信,推荐信基本上就是复试的入场券,所以一定要提前联系老师,拿到推荐信。只要有机会进了面试,我觉得老师对于双非并不歧视,面试的个人表现才是关键性决定因素,技巧性也是很强的,如果有需要帮助的,欢迎私信~~

D1379951481的博客 3368

设计模式之代理模式(ProxyPattern)

设计模式之代理模式(ProxyPattern) 1.图和分析 有三个角色: 代理角色 :房屋中介,代理真实角色,一般会进行一些附属操作 真实角色:房主,执行自己的业务代码即可 抽象角色:租房,一般是接口或者抽象类 2.静态代理 根据上面的图,代码实现 租房接口(interface) public interface Rent { void rent(); } 房主类,实现...

qq_38056518的博客 243

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

设计模式之代理模式ProxyPattern(六)

1、什么是代理模式?代理模式是23种设计模式中的一种。代理模式是一种结构型设计模式,它允许为其他对象提供一个替代品或占位符,以控制对这个对象的访问。2、代理模式的角色构成抽象主题(Subject):定义了真实主题和代理主题的共同接口,这样代理类可以通过实现该接口来代理真实主题。真实主题(Real Subject):定义了代理所代表的真实对象。代理(Proxy):持有对真实主题的引用,并实现了与真实主题一样的接口,客户端通过代理来访问真实主题,同时可以在访问真实主题前后进行一些额外操作。

徐泗空的博客 1466

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

[DesignPattern]ProxyPattern

代理模式玩过扮白脸、扮黑脸的游戏吗?这就是代理要做的:控制和管理访问。还记得状态模式的那台糖果机吗?现在我们需要远程监控糖果机。(在开始编码之前,需要收集需求)。远程代理 远程代理就好比“远程对象的本地代表”。何谓“远程对象“?这是一种对象,活在不同的Java虚拟机(JVM)堆中。 你的客户对象所做的就像是在做远程方法调用,但其实只是调用本地堆中的”代理“上的方法,再由代理处理所有网络通信的低层细节

xy_cpp的博客 417

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

您的设计模式——代理模式【Proxy Pattern 】

什么是代理模式呢?我很忙,忙的没空理你,那你要找我呢就先找我的代理人吧,那代理人总要知道 被代理人能做哪些事情不能做哪些事情吧,那就是两个人具备同一个接口,代理人虽然不能干活,但是被 代理的人能干活呀。 比如西门庆找潘金莲,那潘金莲不好意思答复呀,咋办,找那个王婆做代理,表现在程序上时这样的: 先定义一种类型的女人:package com.alex.patterns.proxy;/**

411

设计模式—代理模式

在代理模式(Proxy Pattern)中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式。 意图:为其他对象提供一种代理以控制对这个对象的访问。 主要解决:在直接访问对象时带来的问题,比如说:要访问的对象在远程的机器上。在面向对象系统中,有些对象由于某些原因(比如对象创建开销很大,或者某些操作需要安全控制,或者需要进程外的访问),直接访问会给使用者或者系统结构带来...

dmxhcwk90096748的博客 99

java设计模式之 代理模式【Proxy Pattern】 详解

首先我们举个例子说明一下什么是策略模式: 什么是代理模式呢?我很忙,忙的没空理你,那你要找我呢就先找我的代理人吧,那代理人总要知道 被代理人能做哪些事情不能做哪些事情吧,那就是两个人具备同一个接口,代理人虽然不能干活,但是被 代理的人能干活呀。 比如西门庆找潘金莲,那潘金莲不好意思答复呀,咋办,找那个王婆做代理,表现在程序上时这样的: 先定义一种类型的女人: package com.cbf4lif...

蛋蛋淡淡定的庄园 299

设计模式代理模式(ProxyPattern)

核心模块:抽象角色,真实角色,代理角色 所有代码请访问:git@code.aliyun.com:289804201/PatternLearn.git 使用场景:适合不方便直接访问对象的情况; 优点:协调了调用者和被调用者,减少耦合,起到了保护目标对象的作用; 缺点:由于使用代理可能会使请求速度变慢; 注意: 1,与中介者模式区别,中介者对中介双方权重

didiao11300的专栏 359

Java设计模式之代理模式

在代理模式(Proxy Pattern)中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式。 在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。 所谓的代理者是指一个类别可以作为其它东西的接口。代理者可以作任何东西的接口:网上连接、存储器中的大对象、文件或其它 昂贵或无法复制的资源。 著名的代理模式例子为引用计数(英语:reference counting)指针...

Expaner的博客 172

设计模式(DesignPattern)之代理模式(Proxy)

1、定义         代理模式也称为委托模式,为一个对象提供一个代理对象,以此来控制被代理对象的访问,简单来说就是代理对象代替被代理对象来完成一些事情。         代理模式一般分为静态代理和动态代理:         静态代理:代理类在代码编译以前就已经存在。         动态代理:运行时动态的创建代理对象,可以很灵活的代理自己想要代理的对象,通过反射机制来实现。 2、使用...

inventor1024的博客 536

设计模式---代理模式(DesignPattern_Proxy)

摘录自:设计模式与游戏完美开发 十年磨一剑,作者将设计模式理论巧妙地融入到实践中,以一个游戏的完整实现呈现设计模式的应用及经验的传承 《轩辕剑》之父——蔡明宏、资深游戏制作人——李佳泽、Product Evangelist at Unity Technologies——Kelvin Lo、信仁软件设计创办人—— 赖信仁、资深3D游戏美术——刘明恺 联合推荐全书采用了整合...

su9257的博客 139

《设计模式》代理模式

定义代理模式就是为被访问的目标对象提供一个代理,此时代理对象充当访问对象和目标对象之间的媒介,通过代理对象实现对目标对象的访问。被代理的对象可以是远程对象、创建开销大的对象以及需要安全控制的对象,Java 中的代理按照代理的生成时机不同分为静态代理和动态代理,静态代理就是在编译期就生成代理对象,而动态代理是在 Java 运行时动态生成,而动态代理又分为 JDK 动态代理和 Cglib 动态代理两种。代理模式的角色组成抽象主题类(Subject):通过接口或抽象类声明真实主题和代理对象实现的业务方法。

华仔仔的博客 4001

设计模式 - 学习笔记 - 代理模式ProxyPattern

设计模式 - 学习笔记 - 代理模式ProxyPattern学习总结要点总结UML参考资料 学习总结 既然叫代理,就想一下我们什么情况用代理——不方便直接访问(控制)的时候。比如:分布式、AOP 所以核心就是间接访问(控制) 要点总结 “增加一层间接层"是软件系统中对许多复杂问题的一种常见解决方法。在面向对象系统中,直接使用某些对象会带来很多问题,作为间接层的proxy对象便是解决这一问题的常用手段。 具体proxy设计模式的实现方法、实现粒度都相差很大,有些可能对单个对象做细粒度的控制,如copy-

灵台方寸山斜月三星洞 495
上一篇: 设计模式之单例模式
下一篇: springboot2入门
西红柿丶番茄
博客等级 码龄10年 21粉丝 41原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值