前言
我在上一篇文章收尾部分提到过,设计模式按照功能性分为三类:创建类、结构类、行为类。创建类设计模式应用于创建对象这一步,包含工厂模式、单例模式、建造者模式、原型模式,通过之前的四篇文章已经全部介绍完。
从本篇开始介绍结构类设计模式,在创建类模式创建好对象之后,结构类模式的作用是负责对代码作结构优化以及解耦。下面开始介绍结构类第一种--代理模式。
本文能为读者创造的价值:
1. 了解什么是代理模式
2. 代理模式的作用
3. 代理模式的应用场景
4. 代理的实现方式
掌握设计模式的三个过程:
- 理解:通过本文理解设计模式
- 识别:阅读代码的时候能够识别出应用了哪种设计模式
- 应用:当接到业务的时候,能够反应出可以应用哪种设计模式并加以实现(读者想要达到这个程度,需要反复重复“识别”的过程)
什么是代理模式
代理模式是在用户与请求的服务之间增加一层代理类用于拦截请求,并在代理类中对请求的服务做业务扩展,以达到业务解耦的目的。也就是说用户不直接与服务交互,用户的请求会先经过代理类,然后代理类与真正的服务交互。
场景模拟:“你的项目里日志记录是怎么做的“
这个问题读者在面试的时候大概率会被问到,其实本质是在问你“代理模式如何实现”,这正是本篇文章对读者的价值所在。日志记录操作跟主业务并无关联,为了代码解耦,提高扩展性,考虑将这部分逻辑分离出来,于是代理模式就成了最佳思路。
来看具体实现方式:
准备工作,先定义一个服务(producer)
一、静态代理
调用代理类:
以上就是静态代理。通过代码和其中的注释读者应该对代理模式有所体会。不过这里想跟读者科普一个专业术语:方法增强(知道的读者可以直接跳过直接看动态代理了
)。方法增强是指对原方法进行解耦式的业务扩展,上面接口代理类中的makeProduct()方法就是对原实现类方法做了方法增强,请读者细细体会。
之所以要跟读者特别说明一些专业术语是因为它是我们专业水平的一个体现,相像一下你跟小白萌妹子科普方法增强概念的场景,你的身后是带着光的
,它对我们不管是日常工作交流还是面试都很有帮助。好了回归正题,继续下一种实现方式:
二、动态代理
通过静态代理我们实现了日志记录和主业务的解耦。现在需要普及这个模式了,把项目里所有的接口都做代理,那么问题来了,那么多接口每个都要创建个代理类,工作量难以想象,那怎么办呢?使用动态代理。
来看一下动态代理的设计思路:不需要读者自己创建代理类。而是创建一个公共的代理配置类,在某个服务需要做代理的时候通过代理配置类自动生成对应服务的代理类。也就是说在需要的时候自动创建代理类,这就是所谓的“动态”。
看代码实现:还是之前的ProducerService服务
调用示例:
动态代理的实现逻辑比较复杂
,读者需要反复阅读几次
,多加推敲,才能慢慢理解,先不要着急往下看,多体会几次上面的逻辑思路。
总结一下动态代理的思路:
1. 创建代理配置类并实现InvocationHandle接口
2. 重写InvocationHandle接口的invoke()方法(用于对原服务方法的业务扩展)
3. 分别创建原服务、代理配置类对象
4. 通过Proxy类的newProxyInstance方法指定并生成需要被代理的服务(传入步骤3创建的对象)
5、通过4生成的代理类对象,调用服务
动态代理模式不管是面试还是实际工作中都比较重要,所以上面的示例建议读者多读几次,仔细体会这个过程。
其实动态代理并没有说完(我上面说的是支持接口的动态代理,如果非接口想实现动态代理则需要通过CGLIB实现),不过鉴于今天的内容多且复杂, 且CGLIB并不常用,所以以后有机会再说。读者先把今天的搞懂吧