前端时间学习springmvc的时候,老是不理解处理器适配器的作用,到今天位置才勉强理解处理器适配器,虽说源码还是看不懂,但也勉强收获,或者是理解了一个设计模式。
设计模式之适配器模式
在springmvc中,用户向服务器发送请求,前端控制器接受请求,调用处理器适配器传递url得到处理器,调用处理器适配器才能执行这个请求,并返回modelAndView,处理器适配器在这里扮演了一个很重要的角色,因为你的handler并不知道是属于那个控制器(controller有老多种啊),所以它的通过处理器适配器来找到控制器,继而执行handler,返回modelandview。
适配器模式的概念
适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。
举个例子
用电器做例子,笔记本电脑的插头一般都是三相的,即除了阳极、阴极外,还有一个地极。而有些地方的电源插座却只有两极,没有地极。电源插座与笔记本电脑的电源插头不匹配使得笔记本电脑无法使用。这时候一个三相到两相的转换器(适配器)就能解决此问题,而这正像是本模式所做的事情。
适配器模式有类的适配器模式和对象的适配器模式两种不同的形式。
类适配器模式:
原理:通过继承来实现适配器功能。
当我们要访问的接口A中没有我们想要的方法 ,却在另一个接口B中发现了合适的方法,我们又不能改变访问接口A,在这种情况下,我们可以定义一个适配器p来进行中转,这个适配器p要实现我们访问的接口A,这样我们就能继续访问当前接口A中的方法(虽然它目前不是我们的菜),然后再继承接口B的实现类BB,这样我们可以在适配器P中访问接口B的方法了,这时我们在适配器P中的接口A方法中直接引用BB中的合适方法,这样就完成了一个简单的类适配器。
定义想要使用功能的接口
/**
* @Description:这是一个电脑,只能插入圆形插口的耳机
* @Author: zc
* @CreateDate: 2018/12/16$ 21:15$
*/
public interface CirCle {
public void music();
}
定义电脑接口的实现类
/**
* @Description:圆形接口耳机的实现类
* @Author: zc
* @CreateDate: 2018/12/16$ 21:20$
*/
public class CirCleBean implements CirCle {
@Override
public void music() {
System.out.println("我是圆形接口的耳机,听歌啊");
}
}
定义适配器,通过这个适配器可以间接的插入电脑
/**
* @Description:我是适配器,圆形正方形耳机插入我,我插入电脑的圆形接口,你就能听歌了
* @Author: zc
* @CreateDate: 2018/12/16$ 21:24$
*/
public class AdapterFormSquToCir extends CirCleBean implements Square {
//主人带的二级还是那个方型的没变。。。
@Override
public void squareMusic() {
music();
}
}
定义测试类
public class Deo1 {
public static void main(String[] args) {
AdapterFormSquToCir adapterFormSquToCir = new AdapterFormSquToCir();
adapterFormSquToCir.squareMusic();
}
}
我是圆形接口的耳机,听歌啊
对象适配器模式
原理:通过组合来实现适配器功能。
当我们要访问的接口A中没有我们想要的方法 ,却在另一个接口B中发现了合适的方法,我们又不能改变访问接口A,在这种情况下,我们可以定义一个适配器p来进行中转,这个适配器p要实现我们访问的接口A,这样我们就能继续访问当前接口A中的方法(虽然它目前不是我们的菜),然后在适配器P中定义私有变量C(对象)(B接口指向变量名),再定义一个带参数的构造器用来为对象C赋值,再在A接口的方法实现中使用对象C调用其来源于B接口的方法。
定义想要使用功能的接口
/**
* @Description:这是一个电脑,只能插入圆形插口的耳机
* @Author: zc
* @CreateDate: 2018/12/16$ 21:15$
*/
public interface CirCle {
public void music();
}
/**
* @Description:圆形接口耳机的实现类
* @Author: zc
* @CreateDate: 2018/12/16$ 21:20$
*/
public class CirCleBean implements CirCle {
@Override
public void music() {
System.out.println("我是圆形接口的耳机,听歌啊");
}
}
定义适配器
/**
* @Description:我是适配器,圆形正方形耳机插入我,我插入电脑的圆形接口,你就能听歌了
* @Author: zc
* @CreateDate: 2018/12/16$ 21:24$
*/
public class AdapterFormSquToCir extends CirCleBean implements Square {
private CirCle cirCle;
public AdapterFormSquToCir(CirCle cirCle) {
this.cirCle = cirCle;
}
//主人带的二级还是那个方型的没变。。。
@Override
public void squareMusic() {
music();
}
}
测试
/**
* @Description:
* @Author: zc
* @CreateDate: 2018/12/16$ 21:29$
*/
public class Deo1 {
public static void main(String[] args) {
AdapterFormSquToCir adapterFormSquToCir = new AdapterFormSquToCir(new CirCleBean());
adapterFormSquToCir.squareMusic();
}
}
4、适配器模式应用场景
类适配器与对象适配器的使用场景一致,仅仅是实现手段稍有区别,二者主要用于如下场景:
(1)想要使用一个已经存在的类,但是它却不符合现有的接口规范,导致无法直接去访问,这时创建一个适配器就能间接去访问这个类中的方法。
(2)我们有一个类,想将其设计为可重用的类(可被多处访问),我们可以创建适配器来将这个类来适配其他没有提供合适接口的类。
以上两个场景其实就是从两个角度来描述一类问题,那就是要访问的方法不在合适的接口里,一个从接口出发(被访问),一个从访问出发(主动访问)。
接口适配器使用场景:
(1)想要使用接口中的某个或某些方法,但是接口中有太多方法,我们要使用时必须实现接口并实现其中的所有方法,可以使用抽象类来实现接口,并不对方法进行实现(仅置空),然后我们再继承这个抽象类来通过重写想用的方法的方式来实现。这个抽象类就是适配器。