Java设计模式——适配器模式
1 类适配器模式
1.1 类适配器模式介绍
Target(目标抽象类)
:目标抽象类定义客户所需接口,可以是一个抽象类或接口,也可以是具体类。
Adapter(适配器类)
:适配器可以调用另一个接口,作为一个转换器,对Adaptee和Target进行适配,适配器类是适配器模式的核心,在对象适配器中,它通过继承Target并关联一个Adaptee对象使二者产生联系。
Adaptee(适配者类)
:适配者即被适配的角色,它定义了一个已经存在的接口,这个接口需要适配,适配者类一般是一个具体类,包含了客户希望使用的业务方法,在某些情况下可能没有适配者类的源代码。
基本介绍:Adapter类,通过继承Adaptee类,实现target接口,完成Adaptee到target的适配
Adaptee类
public class AC220V {
public int output220V() {
int output = 220;
System.out.println("输出220V电压");
return output;
}
}
target类
public interface DC5 {
int output5V();
}
Adapter
public class ChinaPowerAdapter extends AC220V implements DC5 {
@Override
public int output5V() {
int output220 = output220V();
System.out.println("接入220V电压,输出5V电压");
return output220/44;
}
}
通过适配器将220V电压输出转换为需要的5V输出
2 对象适配器模式
2.1 对象适配器模式介绍
基本思路与类适配器模式相同,只是将Adapter类修改,不是继承Adaptee类,而是持有Adaptee的实例
根据“合成复用原则”,在系统中尽量使用关联关系来替代继承关系
对象适配器模式是适配器模式中常用的一种
Adaptee
public class AC220V {
public int output220V() {
int output = 220;
System.out.println("输出220V电压");
return output;
}
}
target类
public interface DC5 {
int output5V();
}
Adapter
public class ChinaPowerAdapter implements DC5 {
private AC220V ac220V;
public ChinaPowerAdapter(AC220V ac220V) {
this.ac220V = ac220V;
}
@Override
public int output5V() {
int output = 0;
if (ac220V != null) {
output = ac220V.output220V() / 44;
}
return output;
}
}
2.2 优点
解决了类适配器必须继承Adaptee的局限性问题,也不再要求target必须是接口
3 接口适配器模式
3.1 接口适配器模式介绍
当不需要全部实现接口提供的方法时,可先设计一个抽象实现接口,并为接口中的每个方法提供一个默认实现(空方法),那么该抽象类的子类可有选择第覆盖父类中的某些方法来实现需求
适用于一个接口不想使用其所有的方法的情况
AC接口
public interface AC {
int output();
}
AC接口实现类
public class AC220V implements AC{
@Override
public int output() {
int output = 220;
System.out.println("输出220V电压");
return output;
}
}
多输出多功能接口
public interface DCOutput {
int output5V();
int output10V();
int output15V();
int output20V();
}
默认实现接口抽象类
public abstract class PowerAdapter implements DCOutput {
protected AC ac;
public PowerAdapter(AC ac) {
this.ac = ac;
}
@Override
public int output5V() {
return 0;
}
@Override
public int output10V() {
return 0;
}
@Override
public int output15V() {
return 0;
}
@Override
public int output20V() {
return 0;
}
}
只关注输出为5V的功能,故重写抽象类的5V方法
public class Test {
public static void main(String[] args) {
PowerAdapter powerAdapter = new PowerAdapter(new AC220V()) {
@Override
public int output5V() {
int output = 0;
if (ac != null) {
output = ac.output() / 44;
}
System.out.println("输出5V");
return output;
}
};
powerAdapter.output5V();
}
}
4 源码分析
4.1 SpringMVC执行流程
- 用户发送出请求到前端控制器DispatcherServlet。
- DispatcherServlet收到请求调用HandlerMapping(处理器映射器)。
- HandlerMapping找到具体的处理器(可查找xml配置或注解配置),生成处理器对象及处理器拦截器(如果有),再一起返回给DispatcherServlet。
- DispatcherServlet调用HandlerAdapter(处理器适配器)。
- HandlerAdapter经过适配调用具体的处理器(Handler/Controller)。
- Controller执行完成返回ModelAndView对象。
- HandlerAdapter将Controller执行结果ModelAndView返回给DispatcherServlet。
- DispatcherServlet将ModelAndView传给ViewReslover(视图解析器)。
- ViewReslover解析后返回具体View(视图)。
- DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。
- DispatcherServlet响应用户。
4.2 SpringMVC中的适配器模式
在SpringMVC中默认会存在三种Adapter:HttpRequestHandlerAdapter,SimpleControllerHandlerAdapter和AnnotationMethodHandlerAdapter
,他们会根据Controller的类型来分配任务。
- AnnotationMethodHandlerAdapter主要是适配注解类处理器,注解类处理器就是我们经常使用的@Controller的这类处理器
- HttpRequestHandlerAdapter主要是适配静态资源处理器,静态资源处理器就是实现了HttpRequestHandler接口的处理器,这类处理器的作用是处理通过SpringMVC来访问的静态资源的请求。
- SimpleControllerHandlerAdapter是Controller处理适配器,适配实现了Controller接口或Controller接口子类的处理器,比如我们写Controller来继承MultiActionController.
利用不同的适配器处理不同类型的Controller请求,并将返回的数据封装成ModelAndView返回,完成返回数据的统一。并且使用适配器模式后,以后如果增加其他类型的Controller,只需增加相应的Adapter即可,保证了开闭原则—对扩展开放,对修改关闭
HandlerAdapter接口
public interface HandlerAdapter {
boolean supports(Object var1);
ModelAndView handle(HttpServletRequest var1, HttpServletResponse var2, Object var3) throws Exception;
long getLastModified(HttpServletRequest var1, Object var2);
}
HandlerAdapter接口一个实现
public class HttpRequestHandlerAdapter implements HandlerAdapter {
public HttpRequestHandlerAdapter() {
}
public boolean supports(Object handler) {
return handler instanceof HttpRequestHandler;
}
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
((HttpRequestHandler)handler).handleRequest(request, response);
return null;
}
public long getLastModified(HttpServletRequest request, Object handler) {
return handler instanceof LastModified ? ((LastModified)handler).getLastModified(request) : -1L;
}
}
Spring容器启动后会将配置的HandlerAdapter存放到一个List对象中,当对应的请求来时,在DispatcherServlet的doDispatch方法中找到合适的HandlerAdapter(找到一个就返回),并通过相应的HandlerAdapter完成相应的请求,返回相应ModelAndView
public class DispatcherServlet extends FrameworkServlet {
private List<HandlerAdapter> handlerAdapters;
//初始化handlerAdapters
//根据配置注册handlerAdapters
private void initHandlerAdapters(ApplicationContext context) {
//..省略...
}
// 遍历所有的 HandlerAdapters,通过 supports 判断找到匹配的适配器
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
Iterator var2 = this.handlerAdapters.iterator();
HandlerAdapter ha;
do {
if (!var2.hasNext()) {
throw new ServletException("No adapter for handler [" + handler + "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
}
ha = (HandlerAdapter)var2.next();
if (this.logger.isTraceEnabled()) {
this.logger.trace("Testing handler adapter [" + ha + "]");
}
} while(!ha.supports(handler));
return ha;
}
// 分发请求,请求需要找到匹配的适配器来处理
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
ModelAndView mv = null;
// Determine handler for the current request.
mappedHandler = getHandler(processedRequest);
// 确定当前请求的匹配的适配器.
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
ha.getLastModified(request, mappedHandler.getHandler());
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
}
// ...省略...
}
5 仿照例子
AC接口
public interface AC {
int outputAC();
}
AC110实现类
public class AC110 implements AC {
@Override
public int outputAC() {
return 110;
}
}
AC220实现类
public class AC220 implements AC {
@Override
public int outputAC() {
return 220;
}
}
Adapter接口
public interface DC5Adapter {
int outputDC5V(AC output);
boolean support(AC output);
}
Adapter实现类
public class ChinaPowerAdapter implements DC5Adapter {
@Override
public int outputDC5V(AC output) {
int chinaOutput = output.outputAC();
System.out.println("使用ChinaPowerAdapter变压适配器");
return chinaOutput/44;
}
@Override
public boolean support(AC output) {
return 220==output.outputAC();
}
}
Adapter实现类
public class JapanPowerAdapter implements DC5Adapter {
@Override
public int outputDC5V(AC output) {
int japanOutput = output.outputAC();
System.out.println("使用JapanPowerAdapter变压适配器");
return japanOutput/22;
}
@Override
public boolean support(AC output) {
return 110==output.outputAC();
}
}
测试
public class Test {
private List<DC5Adapter> adapters = new ArrayList<>();
//注册Adapter
public Test() {
adapters.add(new ChinaPowerAdapter());
adapters.add(new JapanPowerAdapter());
}
//根据support方法找到合适的Adapter
public DC5Adapter getFitAdapter(AC ac) {
DC5Adapter dc5Adapter = null;
for (DC5Adapter temp : adapters) {
if (temp.support(ac)) {
dc5Adapter = temp;
break;
}
}
return dc5Adapter;
}
public static void main(String[] args) {
Test test = new Test();
AC china = new AC220();
AC japan = new AC110();
DC5Adapter fitAdapter = test.getFitAdapter(china);
fitAdapter.outputDC5V(china);
DC5Adapter fitAdapter1 = test.getFitAdapter(japan);
fitAdapter1.outputDC5V(japan);
}
}