适配器模式是将一个类的接口转换成客户希望的另一个接口,从而让那些接口不兼容的类可以一起工作。
一、类图结构
适配器模式包含一下三个角色:
- Target(目标抽象类):目标抽象类定义客户所需的接口,可以是一个抽象类或接口,也可以是具体类。在类适配器中,由于C#语言不支持多重继承,所以它只能是接口。
- Adapter(适配器类):它可以调用另一个接口,作为一个转换器,对Adaptee和Target进行适配。它是适配器模式的核心。
- Adaptee(适配者类):适配者即被适配的角色,它定义了一个已经存在的接口,这个接口需要适配,适配者类包好了客户希望的业务方法。
将上面的类图可以转换如下的代码
public class AdapterClient { private List<Adaptor> adaptors = new ArrayList<Adaptor>(); public AdapterClient(){ adaptors.add(new Target1Adaptor()); adaptors.add(new Target2Adaptor()); } /** * 获取目标对象对应的适配器 */ public Adaptor getAdaptor(Target target) { for (Adaptor adaptor : this.adaptors) { if (adaptor.supports(target)) { return adaptor; } } return null; } public static void main(String[] args) { AdapterClient client = new AdapterClient(); //目标 Target target = new Target1(); //Target target = new Target2(); //获取目标对应的适配器 Adaptor adaptor = client.getAdaptor(target); //处理 adaptor.specificRequest(target); } } /** * 适配器接口 */ interface Adaptor { /** * 当前适配器是否支持该目标 */ boolean supports(Target target); /** * 调用支持的目标对象的处理方法。仅当support()返回true时调用 */ void specificRequest(Target target); } /** * 目标1适配器 */ class Target1Adaptor implements Adaptor { @Override public boolean supports(Target target){ //仅支持Target1 return (target instanceof Target1); } @Override public void specificRequest(Target target) { ((Target1)target).request(); } } /** * 目标2适配器 */ class Target2Adaptor implements Adaptor { @Override public boolean supports(Target target) { //仅支持Target2 return (target instanceof Target2); } @Override public void specificRequest(Target target) { ((Target2)target).request(); } } /** * 被适配的目标接口:Adaptee */ interface Target { void request(); } /** * 具体的目标1 */ class Target1 implements Target{ @Override public void request() { System.out.println("Target1正在处理"); } } /** * 具体的目标2 */ class Target2 implements Target { @Override public void request() { System.out.println("Target2正在处理"); } }
二、示例
在SpringMVC中,DispatcherServlet类中的doDispatch方法在查找Controller时,就用到了适配器模式,可以参考DispatcherServlet的工作原理。
下面我们就来简单的应用一下该设计模式。
Controller
interface Controller { void handleRequest(); } class HttpRequestHandler implements Controller { @Override public void handleRequest() { System.out.println("HttpRequestHandler正在处理请求"); } } class RequestMappingHandler implements Controller { @Override public void handleRequest() { System.out.println("RequestMappingHandler正在处理请求"); } } class SimpleHandler implements Controller { @Override public void handleRequest() { System.out.println("SimpleHandler正在处理请求"); } }
HandlerAdaptor
interface HandlerAdaptor { boolean supports(Object handler); void handle(Object handler); } class HttpRequestHandlerAdapter implements HandlerAdaptor{ @Override public boolean supports(Object handler) { return (handler instanceof HttpRequestHandler); } @Override public void handle(Object handler) { ((HttpRequestHandler)handler).handleRequest(); } } class RequestMappingHandlerAdapter implements HandlerAdaptor { @Override public boolean supports(Object handler) { return (handler instanceof RequestMappingHandler); } @Override public void handle(Object handler) { ((RequestMappingHandler)handler).handleRequest(); } } class SimpleHandlerAdapter implements HandlerAdaptor { @Override public boolean supports(Object handler) { return (handler instanceof SimpleHandler); } @Override public void handle(Object handler) { ((SimpleHandler) handler).handleRequest(); } }
DispatcherServlet
public class DispatcherServlet { private List<HandlerAdaptor> handlerAdaptors = new ArrayList<HandlerAdaptor>(); public DispatcherServlet() { handlerAdaptors.add(new RequestMappingHandlerAdapter()); handlerAdaptors.add(new HttpRequestHandlerAdapter()); handlerAdaptors.add(new SimpleHandlerAdapter()); } public HandlerAdaptor getHandler(Controller controller) { for (HandlerAdaptor adapter : this.handlerAdaptors) { if (adapter.supports(controller)) { return adapter; } } return null; } /** * 请求分发 */ public void doDispatch() { // 模拟SpringMVC从request取handler的对象。 //HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); //Controller controller = new HttpRequestHandler(); //Controller controller = new RequestMappingHandler(); Controller controller = new SimpleHandler(); // 不论何种类型Controller,总是通过获取对应的适配器。 HandlerAdaptor ha = getHandler(controller); // Controller处理请求 ha.handle(controller); } public static void main(String[] args) { // 实例化DisPatcherServlet DispatcherServlet dispatch = new DispatcherServlet(); // 请求处理分发 dispatch.doDispatch(); } }
由于Controller的类型不同,有多种实现方式,而且调用方式是不确定,如果直接调用Controller方法,则代码中就会出现较多的if-else。因此Spring定义了一个适配接口,使得每一种Controller有一种对应的适配器实现类,让适配器代替controller执行相应的方法。这样在扩展Controller 时,只需要增加一个适配器类就完成了SpringMVC的扩展了,这就是适配器模式的精妙之处!
……更多设计模式的内容,可以访问Refactoring.Guru