设计模式——适配器模式
适配器模式可能是平常项目中用的最多的设计模式,是一个很简单的设计模式。
一、定义与代码实现
1、定义
- 将某个类的接口转换成客户端期望的另一个接口。
- 适配器模式可以消除由于接口不匹配所造成的类兼容性问题。
2、UML类图
在调用远程接口时,适配器模式是非常有用的,当远程接口变化时,可以建立一个适配器来解决新旧接口产生的兼容性问题,而不需要修改业务层代码。
3、简单代码实现
远程接口从PersonVO改成UserVO,Adaptor进行转换适配
public class UserVO implements Serializable { private static final long serialVersionUID = 1L; private Long id; private String name; private Integer age; //省略getter/setter/toString } public interface Adaptee { void methodB(UserVO userVO); } public class AdapteeImp implements Adaptee { @Override public void methodB(UserVO userVO) { System.out.println(userVO); } } public class PersonVO implements Serializable { private static final long serialVersionUID = 1L; private Long id; private String name; private Integer age; //省略getter/setter/toString } public interface Adaptor { void methodA(PersonVO personVO); } public class AdaptorImp implements Adaptor { private Adaptee adaptee; public AdaptorImp(Adaptee adaptee){ this.adaptee = adaptee; } @Override public void methodA(PersonVO personVO) { UserVO userVO = new UserVO(); userVO.setId(personVO.getId()); userVO.setName(personVO.getName()); userVO.setAge(personVO.getAge()); adaptee.methodB(userVO); } } public class Client { public static void main(String[] args) { PersonVO personVO = new PersonVO(); personVO.setId(9527L); personVO.setName("hua an"); personVO.setAge(18); Adaptee adaptee = new AdapteeImp(); Adaptor adaptor = new AdaptorImp(adaptee); adaptor.methodA(personVO); } }
二、框架中的适配器模式
1、SpringMVC中的HanderAdapter
前面SpringMVC——DispatcherServlet中学习过HandlerMapping与HanderAdapter的初始化与作用了。
在SpringIOC初始化后,SpringMVC会完成多个HandlerMapping与HanderAdapter的Bean初始化,并放入到SpringIOC容器中。
其中常用的两个组件:RequestMappingHandlerMapping与RequestMappingHandlerAdapter
RequestMappingHandlerMapping初始化执行afterPropertiesSet()方法时
- 会扫描所有的@Controller+@RequestMapping注解生成<url,HandlerMethod>容器,
- 会扫描SpringIOC容器中所有实现拦截器接口HandlerInterceptor的拦截器interceptors
假设现在没有RequestMappingHanderAdapter,那么RequestMappingHandlerMapping和@Controller控制器的方法就是直连的,
这个时候@Controller控制器中方法就类似于早期的spring+servlet实现,必须定义为
//@Controller控制器中的方法 public void sayHello(HttpRequest request, HttpResponse response);//参数是request+response //方法流程,省略拦截器逻辑 HandlerMethod handlerMethod = uriMap.get(url) Response response = Method.invoke(handlerMethod,request)
SpringMVC加入了HandlerAdapter适配器就是对方法参数的一个巨大优化
RequestMappingHandlerAdapter初始化执行afterPropertiesSet()方法时:总共定义了20+个request解析器,和10+个response解析器
这些解析器的作用:handlerMethod的参数不再是固定的request+response,可以是任何类型的对象
//@Controller控制器中的方法 public User selectUser(User user);//参数不再固定为request+response,可以为任何类型 //方法流程,省略拦截器逻辑 HandlerMethod handlerMethod = uriMap.get(url) //根据HandlerMethod找到对应的HandlerAdapter HandlerAdapter handlerAdapter = getHandlerAdapter(handlerMethod.getHandler); //HandlerAdapter中的参数解析器会利用request中的参数,初始化一个User对象传入到HandlerMethod方法中, //并且还会将HandlerMethod返回User结果对象,通过返回参数解析器转化成response //解析的细节比较复杂,后续学习 ModelAndView mv = handlerAdapter.handler(request,response,handlerMethod.getHandler())