继续创作,加速成长!这是我参加「日新方案 10 月更文挑战」的第16天,点击检查活动详情
前言
适配器形式应用十分广泛,咱们日子中很多事物都运用了适配器形式,比如日子中常见的手机充电的场景,咱们都知道家庭中插座电压是220V,但是咱们手机数据线上标注的却是5V-3A、10V-4A,那么手机是如何从220V的电压中充电的呢?关键就是那个充电头充当了适配器的形式,将电压转换为手机能承受的小电压,适配器形式也是这样的原理。
适配器形式作业原理
- 将一个类的接口转换成另一种接口,让本来接口不兼容的类能够兼容
- 从用户的视点看不到被适配者,是解耦的
- 用户调用适配器转化出来的方针接口办法,适配器再调用被适配者的相关接口办法
- 用户收到反应成果,感觉仅仅和方针接口交互。
适配器形式完结
适配器形式有三种比较常见的完结方式:
- 类适配器形式
- 目标适配器形式
- 接口适配器形式
类适配器形式
简单来说就是Adapter类经过承继src类,完结dst接口完结src到dst的适配。 src类界说源220V输出电压
public class Voltage220V {
public int OutPut220(){
int src = 220;
System.out.println("输出电压220");
return src;
}
}
dst界说接口输入5v电压
interface Voltage5V {
public int OutPut5();
}
Adapter承继src,完结dst
public class VoltageAdapter extends Voltage220V implements Voltage5V{
@Override
public int OutPut5() {
int src = OutPut220();
int dst = src/44;
System.out.println("适配器转为5V");
return dst;
}
}
手机调用dst接口输入5v办法进行充电,实际上调用的是Adaoter类中完结dst的output5()办法。
public class Phone {
public void Charge(Voltage5V voltage5V){
int dst = voltage5V.OutPut5();
System.out.println("5V充电");
}
}
总结:
- Java是单承继机制,反以类适配器需求承继src类这一点算是一个缺陷,因为这要求dst有必要是接口,有一定局限性;
- src类的办法在Adapter中都会暴露出来,也增加了运用的本钱。
- 因为其承继了src类,所以它能够依据需求重写src类的办法,使得Adapter的灵活性增强了。
目标适配器形式
基本思路和类的适配器形式相同,仅仅将Adapter类作修正,不是承继src类,而是持有src类的实例,切处理兼容性的问题。即:持有src类,完结 dst 类接口,完结src->dst的适配。
在Adapter类中,不再承继src,而是创立Voltage220V实例目标
public class VoltageAdapter implements Voltage5V {
private Voltage220V voltage220V;
public VoltageAdapter(Voltage220V voltage220V) {
this.voltage220V = voltage220V;
}
@Override
public int OutPut5() {
int src = voltage220V.OutPut220();
int dst = src/44;
System.out.println("适配器转为5V");
return dst;
}
}
目标适配器和类适配琴其实算是同一种思想,只不过完结方式不同。 依据合成复用准则,运用组合代替承继,所以它处理了类适配器有必要承继src的局限性问题,也不再要求dst有必要是接口。运用本钱更低,更灵活。
接口适配器形式
当不需求全部完结接口供给的办法时,可先设计一个抽象类完结接口,并为该接中每个办法供给一个默许完结(空办法),那么该抽象类的子类可有挑选地掩盖父类的某些办法来完结需求。
接口界说办法
public interface test {
public void m1();
public void m2();
public void m3();
public void m4();
}
抽象类为接口中的办法供给空完结
public abstract class testAdapter implements test{
public void m1(){}
public void m2(){}
public void m3(){}
public void m4(){}
}
运用时针对需求的办法进行完结
public class Client {
public static void main(String[] args) {
testAdapter adapter = new testAdapter(){
public void m1(){
System.out.println("完结m1办法");
}
};
adapter.m1();
}
}
接口适配器形式适用于不需求src一切办法的场景。
手写SpringMVC中的适配器
首先回顾一下SpringMVC的作业原理:
- 用户发送恳求至前端控制器DispatcherServlet。
- DispatcherServlet收到恳求调用HandlerMapping处理器映射器。
- 处理器映射器找到详细的处理器(能够依据xml装备、注解进行查找),生成处理器目标及处理器拦截器(如果有则生成)一并回来给DispatcherServlet.
- DispatcherServlet调用HandlerAdapter处理器适配器。
- HandlerAdapter经过适配调用详细的处理器(Controller,也叫后端控制器)。
- Controller履行完结回来ModelAndView。
- HandlerAdapter将controller履行成果ModelAndView回来给DispatcherServlet
- DispatcherServlet将ModelAndView传给ViewReslover视图解析器。
- ViewReslover解析后回来详细View。
- DispatcherServlet依据View进行渲染视图(即将模型数据填充至视图中)。DispatcherServlet呼应用户。
要想手写适配器处理流程,首先需求了解类图
恳求抵达DispatchServlet,DispatchServlet需求依据恳求挑选对应的处理器适配器也就是HandlerAdapter,处理器适配器调用对应的处理器Controller。
界说Controller接口,多种Controller完结Controller接口,完结自己的办法。
//多种Controller完结
public interface Controller {
}
class HttpController implements Controller {
public void doHttpHandler() {
System.out.println("http...");
}
}
class SimpleController implements Controller {
public void doSimplerHandler() {
System.out.println("simple...");
}
}
class AnnotationController implements Controller {
public void doAnnotationHandler() {
System.out.println("annotation...");
}
}
界说HandleAdapter,依据Controller完结对应的适配器
///界说一个Adapter接口
public interface HandlerAdapter {
public boolean supports(Object handler);
public void handle(Object handler);
}
// 多种适配器类
class SimpleHandlerAdapter implements HandlerAdapter {
public void handle(Object handler) {
((SimpleController) handler).doSimplerHandler();
}
public boolean supports(Object handler) {
return (handler instanceof SimpleController);
}
}
class HttpHandlerAdapter implements HandlerAdapter {
public void handle(Object handler) {
((HttpController) handler).doHttpHandler();
}
public boolean supports(Object handler) {
return (handler instanceof HttpController);
}
}
class AnnotationHandlerAdapter implements HandlerAdapter {
public void handle(Object handler) {
((AnnotationController) handler).doAnnotationHandler();
}
public boolean supports(Object handler) {
return (handler instanceof AnnotationController);
}
}
DispatchServlet进行分发
public class DispatchServlet {
//适配器列表
public static List<HandlerAdapter> handlerAdapters = new ArrayList<HandlerAdapter>();
//将适配器添加到列表
public DispatchServlet() {
handlerAdapters.add(new AnnotationHandlerAdapter());
handlerAdapters.add(new HttpHandlerAdapter());
handlerAdapters.add(new SimpleHandlerAdapter());
}
//适配器分配
public void doDispatch() {
// 此处模拟SpringMVC从request取handler的目标,
// 适配器能够获取到希望的Controller
HttpController controller = new HttpController();
// AnnotationController controller = new AnnotationController();
//SimpleController controller = new SimpleController();
// 得到对应适配器
HandlerAdapter adapter = getHandler(controller);
// 经过适配器履行对应的controller对应办法
adapter.handle(controller);
}
public HandlerAdapter getHandler(Controller controller) {
//遍历:依据得到的controller(handler), 回来对应适配器
for (HandlerAdapter adapter : this.handlerAdapters) {
if (adapter.supports(controller)) {
return adapter;
}
}
return null;
}
public static void main(String[] args) {
new DispatchServlet().doDispatch(); // http...
}
}