版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。
在适配器模式中,我们通过增加一个新的适配器类来解决接口不兼容的问题,使得原本没有任何关系的类可以协同工作。
一、先从一个问题说起
之前负责的项目中遇到过一个问题:
在InterceptorAdapter拦截器中对请求进行验证,把验证信息传给日志服务平台做统计。正常普通接口请求,request.getParameter()可以获取,能多次读取。
但是,如果我们的接口是用@RequestBody来接受数据,就会报异常:java.io.IOException: Stream closed。
这是因为流是一次性的,@RequestBody注解也是根据流的形式获取参数,拦截器中 request使用流获取参数后,@RequestBody注解就不能再次使用了。
两个都要使用stream,流又是一次性的,那这个问题怎么解决?有个重写HttpServletRequestWrapper的方案,这个HttpServletRequestWrapper就是一个包装类,使用了适配器模式,因此适配器又叫包装模式。大家可以在看完本文后,去研究下HttpServletRequestWrapper,这也是适配器模式的具体应用。
二、什么适配器模式?
适配器模式的主要作用是将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
怎么理解?就好比下面的图:
这个老显示器只兼容VGA数据线,但是当前只有一条HDMI的数据线,怎么才能使用这个显示器呢?
那就是加上一个HDMI转VGA的转换器,把HDMI的数据线转成VGA接口即可,但这里真正工作的还是HDMI的数据线,并不是制造出了一条VGA数据线。
所以适配器起到的是一个中间转换的作用,把原来不兼容的东西组合起来,实现想要的功能。
三、适配器模式实现
GOF中将适配器模式分为类适配器模式和对象适配器模式。
在对象适配器模式中,适配器与适配者之间是关联关系;在类适配器模式中,适配器与适配者之间是继承(或实现)关系。
这么说有点难理解,那就先看代码,适配器的实现是比较简单的,无论是HDMI数据线还是VG