type
status
date
slug
summary
tags
category
icon
password
💡
代理模式是为其他对象提供一种代理以控制对这个对象的访问。往往被代理对象是不希望被直接访问的(个人认为这是和装饰器模式的一个重要区别),通过代理模式我们可以在被代理对象方法的执行前后增加一些功能(是不是很像AOP),例如记录日志、设置缓存等。代理模式分为静态代理和动态代理,其中动态代理是比较重要的。

使用场景

无法或不想直接访问某个对象访问某个对象存在困难时,可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,委托对象与代理对象需要实现相同的接口。

角色

  1. Subject:抽象主题类,该类的主要职责是申明真实主题与代理的共同接口方法,该类即可以是一个抽象类也可以是一个接口。
  1. RealSubject:真实主题类,该类也称为被委托类或被代理类,该类定义了代理所表示的真实对象,由其执行具体的业务逻辑方法,而客户类则通过代理类间接地调用真实主题类中定义的方法。
  1. ProxySubject:代理类,该类也称为委托类或代理类,该类持有一个对真实主题类的引用,在其所实现的接口方法中调用真实主题类中响应的接口方法执行,以此起到代理的作用。

结构

notion image

静态代理

这里举一个简单的例子,安卓卡顿问题排查的时候经常需要打印方法的执行时间,做法就是在方法的开始和结尾处获取系统时间,再做差打印出来。下面我们假设绘制地图是一个耗时操作,现在我们要在绘制的时候打印绘制时间,代码如下:
kotlin版代码如下,使用by关键字,整体思路一样

动态代理

静态代理是不是看起来很简单,但动态代理才是我们这篇文章的重点,接着上面说如果我们有很多类和方法都要打印耗时,那用静态代理需要搞一堆代理类,同时还有新建大量的接口,实现起来不现实。
这个时候就要用到动态代理,所谓动态代理就是在程序运行时,动态地为被代理对象生成代理类,这需要借助java的反射。
Java的动态代理需要使用InvocationHandler接口和Proxy类。

动态代理和静态代理

1.静态代理中,代理类和真实类实现的是同一个接口,重写同样的方法;jdk动态代理中,代理类和真实类关系不大,代理类实现无侵入式的代码扩展。 2.静态代理中当接口中方法增加的时候,在代理类代码量也会增加,显然是不妥的;jdk动态代理解决了这个问题,当业务增加,代理类的代码不会增加。 3.jdk动态代理实现的是jdk自带InvocationHandler接口,实现了这个接口的类也叫拦截器类,也叫代理类。

装饰器模式和代理模式

让别人帮助你做你并不关心的事情,叫代理模式 为让自己的能力增强,使得增强后的自己能够使用更多的方法,拓展在自己基础之上的功能的,叫装饰器模式
这两种模式的写法没太大区别,只是使用场景或者说语义上的区别
对装饰器模式来说,装饰者(decorator)和被装饰者(decoratee)都实现同一个 接口。对代理模式来说,代理类(proxy class)和真实处理的类(real class)都实现同一个接口。他们之间的边界确实比较模糊,两者都是对类的方法进行扩展,具体区别如下:
1、装饰器模式强调的是增强自身,在被装饰之后你能够在被增强的类上使用增强后的功能。增强后你还是你,只不过能力更强了而已;代理模式强调要让别人帮你去做一些本身与你业务没有太多关系的职责(记录日志、设置缓存)。代理模式是为了实现对象的控制,因为被代理的对象往往难以直接获得或者是其内部不想暴露出来。
2、装饰模式是以对客户端透明的方式扩展对象的功能,是继承方案的一个替代方案;代理模式则是给一个对象提供一个代理对象,并由代理对象来控制对原有对象的引用;
3、装饰模式是为装饰的对象增强功能;而代理模式对代理的对象施加控制,但不对对象本身的功能进行增强;

使用实例Retrofit

提起Retrofit最经常问的就是动态代理了,Retrofit还使用了反射、注解等后面单写一篇Retrofit的源码分析。
首先我们回顾一下retrofit的基本用法,先创建一个接口,通过注解指定请求方式和路径
在项目中创建一个Retrofit实例,并为上一步创建的接口指定一个baseUrl
retrofit通过create方法创建实例,retrofit在create中使用了动态代理,将我们写接口变成可以实现网络请求的方法。create代码如下:
 
 

📎 参考

下面写的很好
装饰器模式(ContextWrapper)观察者模式(EventBus)
LuluNotion
LuluNotion
一个普通的干饭人🍚
公告
type
status
date
slug
summary
tags
category
icon
password
🎉NotionNext 4.0即将到来🎉
-- 感谢您的支持 ---
👏欢迎更新体验👏