引言
最近在读springMVC源码的时候,发现在springMVC的整个流程架构当中,适配器模式是一个非常经典的应用,当然适配模式是一个比较简单的设计模式。
一、springMVC为什么使用适配器模式?
我们知道在springmvc的架构中,控制器(controller)的实现方式有多种,例如直接使用@Controller注解、直接实现 controller接口等, 每一种实现方式都对应不同的处理逻辑,所以如果我们直接调用controller的话,我们的代码就是这个鬼样子,一堆的if else....:
if(mappedHandler.getHandler() instanceof MultiActionController){ ((MultiActionController)mappedHandler.getHandler()).xxx }else if(mappedHandler.getHandler() instanceof XXX){ ... }else if(...){ ... }
如果我们是这样写代码的话, 现在如果又增加了一种controller的实现方式的话,我们就需要在上面方法中增加一个if else,这种形式就使得代码非常不好维护,并且也违反了设计模式中的开闭原则。
因此SpringMVC中 定义了一个适配器接口,使得每一种controller都对应一个 适配器类,让适配器代替controller执行对应的方法,这样我们在扩展controller的时候,只需要增加一个对应的适配器类就可以了。
下面我们看一下, 适配器模式的实现框架:
二、基本概念
适配器模式就是把一个类的接口替换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。
三、适用场景
用电器做例子,笔记本电脑的插头一般都是三相的,即除了阳极、阴极外,还有一个地极。而有些地方的电源插座却只有两极,没有地极。电源插座与笔记本电脑的电源插头不匹配使得笔记本电脑无法使用。这时候一个三相到两相的转换器(适配器)就能解决此问题,而这正像是本模式所做的事情。
四、核心组件
1)目标接口(Target):客户端所期待的接口,目标可以使具体的或抽象类, 也可以是接口
2)需要适配的类(Adaptee):需要适配的类或者适配者类
3)适配器(Adapter):通过包装一个需要适配的对象,把原有接口转换成目标接口
五、两种适配器模式
1、类适配器模式(采用继承方式实现)
目标接口代码:
public interface Target { /** * @Description: 标准接口 * @author: zhenghao * @date: 2020/11/23 20:07 */ void request(); }
普通功能类:
public class ConcreteTarget implements Target { @Override public void request() { System.out.println("实现普通功能。。。"); } }
实现特殊功能的类:
1. public void specificRequest(){ 2. System.out.println("实现特殊功能。。。"); 3. }
适配器类,通过继承实现:
public class Adapter extends Adaptee implements Target { @Override public void request() { //执行父类的方法 super.specificRequest(); } }
测试类:
public class Client { public static void main(String[] args) { //实现普通功能 Target target = new ConcreteTarget(); target.request(); //实现特殊功能 Target adapter = new Adapter(); adapter.request(); } }
2) 对象的适配器模式(通过组合方式实现)
在上述类的适配器的基础上,修改适器类,直接实现标准接口,代码如下:
public class AdapterTwo implements Target { private Adaptee adaptee = new Adaptee(); @Override public void request() { adaptee.specificRequest(); } }
测试类:
public class Client { public static void main(String[] args) { //实现普通功能 Target target = new ConcreteTarget(); target.request(); //实现特殊功能 Target adapter = new AdapterTwo(); adapter.request(); } }
六、小结
6.1 优点
6.1.1 通过适配器,客户端可以调用同一接口,因而对客户端来说是透明的。这样做更简单、更直接、更紧凑。
6.1.2 复用了现存的类,解决了现存类和复用环境要求不一致的问题。
6.1.3 将目标类和适配者类解耦,通过引入一个适配器类重用现有的适配者类,而无需修改原有代码。
6.1.4 一个对象适配器可以把多个不同的适配者类适配到同一个目标,也就是说,同一个适配器可以把适配者类和它的子类都适配到目标接口。
6.2 缺点
对于对象适配器来说,更换适配器的实现过程比较复杂。
6.3 适用场景
6.3.1 系统需要使用现有的类,而这些类的接口不符合系统的接口。
6.3.2 想要建立一个可以重用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。
6.3.3 两个类所做的事情相同或相似,但是具有不同接口的时候。
6.3.4 旧的系统开发的类已经实现了一些功能,但是客户端却只能以另外接口的形式访问,但我们不希望手动更改原有类的时候。
6.3.5 使用第三方组件,组件接口定义和自己定义的不同,不希望修改自己的接口,但是要使用第三方组件接口的功能。
我们彻底了解了适配模式,在入手看springmvc的源码会轻松很多,在下一篇博客,我们将动手,手写一个简易版的springmvc框架!