【设计模式】代理模式-原理、实现以及应用场景

代理模式原理

代理模式(Proxyy)就是在不改变原始类(或叫做被代理类)代码的情况下,通过引入代理类来给原始类附加功能。

静态代理

静态代理在使用时,需要定义接口或者父类,被代理对象(即目标对象)一起实现相同的接口或者是继承相同父类应用实例。

优缺点

优点:
1. 在不修改目标对象的功能前提下,能通过代理对象对目标进行拓展
缺点:
1. 因为代理对象需要与目标对象实现一样的接口,所以会有很多代理类,增加了不必要的开发成本。
2. 一旦接口增加方法,目标对象与代理对象都要维护。

动态代理

动态代理可以解决上述静态代理的缺点问题。
所谓动态代理,就是我们不事先为每个原始类编写代理类,而是在运行的时候,动态地创建原始类对应的代理类,然后在系统中用代理类替换掉原始类。

实现方式

  • JDK实现:InvocationHandler接口
  • CGLib实现:MethodInterceptor接口

CGLIb要求目标代理类中不能有final关键字修饰的方法

JDK动态代理生成对象步骤

  1. 获取被代理对象的引用,并获取它的所有接口,通过反射获取。
  2. JDK动态代理类重新生成一个新类,同时新类实现被代理类实现的所有接口。
  3. 动态生成java代码,新加的业务逻辑方法由一定的代码逻辑调用,$Proxy0。
  4. 编译新生成的java代码.class文件。
  5. 重新加载到JVM中。

CGLib采用了FastClass机制

  1. 为代理类和被代理类各生成一个class。
  2. class会为代理类和被代理类方法分配一个index。
  3. idnex当做入参,FastClass就可以直接定位要调用的方法。

JDK和CGLib对比

实现方式

  • JDK实现了被代理的接口
  • CGLib继承了被代理的接口

生成字节码

  • JDK直接生成字节码
  • CGLib通过asm框架生成class字节码
  • CGlib生成代理类比JDK动态代理效率低

调用代理方法

  • JDK通过反射机制调用
  • CGLib通过FastClass机制直接调用
  • CGLib执行效率比JDK高

静态代理与动态代理区别

静态代理

  1. 只能通过手动完成代理操作,硬编码
  2. 被代理类新增了方法,代理类也要同步增加,违背了开闭原则

动态代理

  1. 采用运行时动态生成代码的方式,反射实现
  2. 对目标类的增加逻辑拓展,只需要新增策略类即可完成,无需修改代理类的代码

代理模式的优缺点

优点

  1. 能将代理对象与真实被调用目标对象分离
  2. 在一定程度上降低了系统的耦合度,拓展性好
  3. 起到保护目标对象的作用
  4. 增强目标对象的功能

缺点

  1. 造成了系统中类的数量增加
  2. 增加了代理对象,会导致请求处理速度变慢
  3. 增加了系统的复杂度

代理模式的应用场景

1. 业务系统的非功能性需求开发

代理模式最常用的一个应用场景就是,在业务系统中开发一些非功能性需求,比如:监控、统计、鉴权、限流、事务、幂等、日志。我们将这些附加功能与业务功能解耦,放到代理类中统一处理,让程序员只需要关注业务方面的开发。实际上,前面举的搜集接口请求信息的例子,就是这个应用场景的一个典型例子。
如果你熟悉 Java 语言和 Spring 开发框架,这部分工作都是可以在 Spring AOP 切面中完成的。前面我们也提到,Spring AOP 底层的实现原理就是基于动态代理。

2. 代理模式在RPC、缓存中的应用

实际上,RPC框架也可以看做是一种代理模式,GoF的《设计模式》一书中把它称作远程代理。通过远程代理,将网络通信,数据编码等细节隐藏起来。客户端在使用RPC服务的时候,就像在使用本地函数一样,无需了解跟服务器交互的细节。除此之外,RPC服务的开发者也只需要开发业务逻辑,就像开发本地使用的函数一样,不需要关注客户端的交互细节。

我们再来看代理模式在缓存中的应用。假设我们要开发一个接口请求的缓存功能,对于某些接口请求,如果入参相同,在设定的过期时间内,直接返回缓存结果,而不用重新进行逻辑处理。比如,针对获取用户个人信息的需求,我们可以开发两个接口,一个支持缓存,一个支持实时查询。对于需要实时数据的需求,我们让其调用实时查询接口,对于不需要实时数据的需求,我们让其调用支持缓存的接口。那如何来实现接口请求的缓存功能呢?最简单的实现方法就是刚刚我们讲到的,给每个需要支持缓存的查询需求都开发两个不同的接口,一个支持缓存,一个支持实时查询。但是,这样做显然增加了开发成本,而且会让代码看起来非常臃肿(接口个数成倍增加),也不方便缓存接口的集中管理(增加、删除缓存接口)、集中配置(比如配置每个接口缓存过期时间)。

针对这些问题,代理模式就能派上用场了,确切地说,应该是动态代理。如果是基于 Spring 框架来开发的话,那就可以在 AOP 切面中完成接口缓存的功能。在应用启动的时候,我们从配置文件中加载需要支持缓存的接口,以及相应的缓存策略(比如过期时间)等。当请求到来的时候,我们在 AOP 切面中拦截请求,如果请求中带有支持缓存的字段(比如 http://…?..&cached=true),我们便从缓存(内存缓存或者 Redis 缓存等)中获取数据直接返回。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 设计模式是软件开发中常用的一种解决方案,它们是一些经过实践验证的可复用设计思想。设计模式允许开发人员在类和对象的结构上灵活地更改,并提供了一种优雅的解决方案来应对各种软件开发问题。 GOF(Gang of Four)是指Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides四位软件工程师,他们在《设计模式:可复用面向对象软件的基础》一书中总结了23种常见的设计模式,这本书因此而获得了“设计模式圣经”的称号。 这本书以案例为基础,深入浅出地讲解了每个设计模式原理应用场景,并提供了C++实现源码。 其中,创建型设计模式包括单例模式、工厂方法模式、抽象工厂模式、建造者模式和原型模式。这些模式都提供了一种方式来创建对象,使得程序在实例化对象时更加灵活和可扩展。 结构型设计模式包括适配器模式、装饰器模式、代理模式、组合模式、享元模式和外观模式。这些模式关注如何通过类和对象的组合来创建更大的结构,并提供了一种优雅的方式来简化系统的复杂性。 行为型设计模式包括策略模式、模板方法模式、观察者模式、迭代器模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式和中介者模式。这些模式关注对象之间的通信和交互,它们提供了一种优雅的方式来实现松耦合和可维护的代码。 总之,设计模式是软件开发中非常重要的一部分,它们提供了一种通用的解决方案来处理常见的设计问题。通过学习和应用设计模式,开发人员可以提高代码的可复用性、可扩展性和可维护性,并加快开发进度。 ### 回答2: 设计模式是软件开发中常用的解决问题的一种思维方式或者说是一种已被证实有效的解决问题的方法。GOF 23种设计模式是由四位著名的软件工程师提出并总结出的一套经典的设计模式。 GOF 23种设计模式分别是创建型模式、结构型模式和行为型模式。创建型模式包括简单工厂模式、工厂方法模式、抽象工厂模式、单例模式、建造者模式和原型模式。结构型模式包括适配器模式、桥接模式、组合模式、装饰器模式、外观模式、享元模式和代理模式。行为型模式包括策略模式、模板方法模式、观察者模式、迭代器模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式和解释器模式。 GOF 23种设计模式具有不同的应用场景和优势。通过学习和理解这些设计模式,开发者可以更加灵活地应对各种软件开发中的问题。同时,掌握这些设计模式也有助于提高代码的可读性、可维护性和可扩展性。 附带C语言实现源码是一种更加具体的学习和理解设计模式的方法。通过查看实现源码,可以更加直观地看到设计模式在实践中的应用。这些源码可以作为学习的参考,帮助开发者更好地理解设计模式的思想和使用方式。 总之,设计模式是软件开发中非常重要的一部分,通过学习GOF 23种设计模式并理解其应用场景和优势,可以提高软件开发的效率和质量。附带C语言实现源码能够更加具体地帮助开发者理解设计模式的实际应用。 ### 回答3: 设计模式是软件工程中常用的一种设计思想或模板,可以用于解决特定的问题和提供可重用的解决方案。GOF(Gang of Four)提出了23种设计模式,并在书籍《设计模式:可复用面向对象软件的基础》中进行了详细的解析和说明。 这本书详细地介绍了23种设计模式,包括创建型模式、结构型模式和行为型模式。通过阅读这本书,读者可以了解每种设计模式的特点、适用场景和实现方法。另外,书中还通过示例代码的方式演示了每种设计模式的具体实现,并提供了附带的C语言实现源码。 这本书对于理解设计模式的概念和思想非常有帮助。它不仅提供了23种设计模式的名字和简介,还详细解释了每种模式的适用场景和应用案例。读者可以通过学习这些设计模式,了解如何将它们应用于自己的软件开发工作中,提高代码的可重用性和可维护性。 书中的C语言实现源码是帮助读者理解和实践设计模式的重要资源。通过阅读源码,读者可以更加深入地理解每种设计模式的具体实现细节,并进一步提升自己的编程能力。 总之,通过学习《设计模式:可复用面向对象软件的基础》这本书,读者可以全面了解设计模式的概念、分类和实现方法,并通过阅读附带的C语言实现源码来加深对设计模式的理解和应用。这将对提升软件设计和开发的能力和水平非常有帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值