设计模式之静态代理和动态代理模式
首先需要理解一下什么是代理的思想:经过我不断的提炼总结以及个人的理解,代理就相当于给类穿上了一个马甲,类本身具有的行为该有的一个没少,却相应的增加了一些功能。举个栗子:在Java的这种垂直的继承实现结构编程中,如果我们有三个不同的动物类,都有吃东西的功能,我想统计它们吃东西的时间,如果按照传统的方式,就必须要调用三次吃东西的方法,每次计算前后时间差。这种时候,代理模式就派上用场了。
传统模式实现
首先定义一个Animal接口,接口方法为eat,吃东西
然后定义三个类分别实现Animal接口
算了定义两个得了
接下来我们使用传统的方式来计算它们吃东西的时长
运行,查看结果:
可见在我八核机器产生的两个小动物都吃的很快。
这里只讨论了两只动物,算是有两个需求,假如我们开了个动物园,有成百上千个动物,我们要统计它们吃东西的时长,难道要每次都写这样繁琐的代码吗?众所周知,写代码的都是一帮懒人,这个时候,代理模式就派上用场了。
静态代理实现
这里我们说静态代理实现统计小动物每次吃东西时长的功能
还是一样,我们有一个Animal接口,有两个可爱的小动物
先来一个猫咪的静态代理类:
再来狗子的:
然后启动客户端:
运行结果:
可以看出来,静态代理实际上就是对对象的管理,委托类拥有被代理对象的全部能力,如果我们想知道动物吃东西的时间,我们就用委托类,不想知道,就用被代理对象,狗子还是那个狗子,只不过增加了一层调用。事实上,设计模式中的很多种都是一种管理对象的思想,AOP面向切面的思想也是,就是一种对对象的管理然后赋予其它的能力。不过我们使用静态代理的方式,动物园每进来一只动物,我们都要为它写一个代理类,这感觉也不是我这种懒人想要的,有没有什么更好的实现方式呢?答案是肯定的!
动态代理
在Java中,动态代理的实现方式有两种,分别是基于接口的JDK动态代理和基于继承的CGLIB动态代理,两种方式差别不是很大,重要的是这种代理的思想。而代理,并不是Java所独有的,这是面向对象编程语言的特性。
JDK动态代理实现
首先来一个Animal动态代理类
这里动态代理就是计算一下小动物的吃饭时间
接下来测试一下
查看输出结果:
这样一来,就算我们动物园里再来超级多个小动物,我们计算吃饭时间的功能已经给它写好了,只需要将动物的对象传到我们的代理类就可以了哦。
CGLIB动态代理实现
首先来一个代理类:(需要将animal接口改为adimal类,dog和cat类继承之)
再来测试:
查看输出结果:
中间这串很奇怪的字符串表示的是CGLIB增强的类,没什么其它的意思。
就像我们平时对日志的处理,事务管理等水平类型的需求,Spring就是使用了动态代理来实现的。总体来讲,设计模式就是为了让我们达到一种编程中理想的状态,尽量不修改已有的类,而使用扩展的方法,避免复用,统一管理。