适配器模式(Adapter Pattern)是指将一个类的接口转换成客户期望的另一个接口,使原本的接口不兼容的类可以一起工作。
属于结构型设计模式
适用场景: 1 已经存在的类,它的方法和需求不匹配(方法结果相同或相似)的情况
2 适配器模式不是软件设计阶段考虑的设计模式,是随着软件维护,由于不同产品、不同厂家造成功能类似而接口不相同情况下的解决方案
public class AC220 { public int outputAC220V() { int output = 220; System.out.println("输出电流" + output + "V"); return output; } }
public interface DC5 { /** * 转换为直流电压 * @return 直流电压 */ int outPutDC5V(); }
public class PowerAdapter implements DC5 { private AC220 ac220; public PowerAdapter(AC220 ac220) { this.ac220 = ac220; } @Override public int outPutDC5V() { int adapterInput = ac220.outputAC220V(); int adapterOutput = adapterInput / 44; System.out.println("使用PowerAdapter输入AC:" + adapterInput + "V,输出DC:" + adapterOutput + "V"); return adapterOutput; } }
public static void main(String[] args) { DC5 dc5 = new PowerAdapter(new AC220()); dc5.outPutDC5V(); }
优点: 1 能提高类的透明性和复用,现有的类复用但不需要改变
2 目标类和适配器类解耦,提高程序的扩展性
3 在很多业务场景中符合开闭原则
缺点: 1 适配器编写过程需要全面考虑,可能会增加系统的复杂性
2 增加代码阅读难度,降低代码可读性,过多使用适配器会使系统代码变得凌乱
public class Member { private String username; private String password; private String mid; private String info; }
public class ResultMsg { private int code; private String msg; private Object data; }
public class SignService { /** * 注册方法 * * @param username * @param password * @return */ public ResultMsg regist(String username, String password) { return new ResultMsg(200, "注册成功", new Member()); } /** * 登录的方法 * * @param username * @param password * @return */ public ResultMsg login(String username, String password) { return null; } }
public class SignForThirdService extends SignService { public ResultMsg loginForQQ(String openId) { //1、openId是全局唯一,我们可以把它当做是一个用户名(加长) //2、密码默认为QQ_EMPTY //3、注册(在原有系统里面创建一个用户) //4、调用原来的登录方法 return loginForRegister(openId, null); } public ResultMsg loginForWechat(String openId) { return null; } public ResultMsg loginForToken(String token) { //通过token拿到用户信息,然后再重新登陆了一次 return null; } public ResultMsg loginForTelphone(String telphone, String code) { return null; } public ResultMsg loginForRegister(String username, String password) { super.regist(username, null); return super.login(username, null); } }
public static void main(String[] args) { SignForThirdService service = new SignForThirdService(); service.login("tom", "123456"); service.loginForQQ("sdfasdfasf"); service.loginForWechat("sdfasfsa"); }
工厂、策略、适配器:
public class Member { private String username; private String password; private String mid; private String info; }
public class ResultMsg { private int code; private String msg; private Object data; }
public class SignService { /** * 注册方法 * * @param username * @param password * @return */ public ResultMsg regist(String username, String password) { return new ResultMsg(200, "注册成功", new Member()); } /** * 登录的方法 * * @param username * @param password * @return */ public ResultMsg login(String username, String password) { return null; } }
/** * 在适配器里面,这个接口是可有可无,不要跟模板模式混淆 * 模板模式一定是抽象类,而这里仅仅只是一个接口 * @author */ public interface LoginAdapter { /** * 判断是否兼容 * @param adapter * @return */ boolean support(Object adapter); /** * 登录是否成功 * @param id * @param adapter * @return */ ResultMsg login(String id,Object adapter); }
public class LoginForQQAdapter implements LoginAdapter { @Override public boolean support(Object adapter) { return adapter instanceof LoginForQQAdapter; } @Override public ResultMsg login(String id, Object adapter) { return null; } }
public class LoginForSinaAdapter implements LoginAdapter { @Override public boolean support(Object adapter) { return adapter instanceof LoginForSinaAdapter; } @Override public ResultMsg login(String id, Object adapter) { return null; } }
public class LoginForTelAdapter implements LoginAdapter { @Override public boolean support(Object adapter) { return adapter instanceof LoginForTelAdapter; } @Override public ResultMsg login(String id, Object adapter) { return null; } }
public class LoginForTokenAdapter implements LoginAdapter { @Override public boolean support(Object adapter) { return adapter instanceof LoginForTokenAdapter; } @Override public ResultMsg login(String id, Object adapter) { return null; } }
public class LoginForWechatAdapter implements LoginAdapter { @Override public boolean support(Object adapter) { return adapter instanceof LoginForWechatAdapter; } @Override public ResultMsg login(String id, Object adapter) { return null; } }
public interface IPassportForThird { /** * QQ登录 * @param id * @return */ ResultMsg loginForQQ(String id); /** * 微信登录 * @param id * @return */ ResultMsg loginForWechat(String id); /** * 记住登录状态后自动登录 * @param token * @return */ ResultMsg loginForToken(String token); /** * 手机号登录 * @param telphone * @param code * @return */ ResultMsg loginForTelphone(String telphone, String code); /** * 注册后自动登录 * @param username * @param passport * @return */ ResultMsg loginForRegist(String username, String passport); }
/** * 结合策略模式、工厂模式、适配器模式 * Created by Tom on 2019/3/16. * @author */ public class PassportForThirdAdapter extends SignService implements IPassportForThird { @Override public ResultMsg loginForQQ(String id) { // return processLogin(id,RegistForQQAdapter.class); return processLogin(id, LoginForQQAdapter.class); } @Override public ResultMsg loginForWechat(String id) { return processLogin(id, LoginForWechatAdapter.class); } @Override public ResultMsg loginForToken(String token) { return processLogin(token, LoginForTokenAdapter.class); } @Override public ResultMsg loginForTelphone(String telphone, String code) { return processLogin(telphone, LoginForTelAdapter.class); } @Override public ResultMsg loginForRegist(String username, String passport) { super.regist(username, passport); return super.login(username, passport); } /** * 简单工厂模式 * @param key * @param clazz * @return */ private ResultMsg processLogin(String key, Class<? extends LoginAdapter> clazz) { try { //适配器不一定要实现接口 LoginAdapter adapter = clazz.newInstance(); //判断传过来的适配器是否能处理指定的逻辑 if (adapter.support(adapter)) { return adapter.login(key, adapter); } } catch (Exception e) { e.printStackTrace(); } return null; } }
public static void main(String[] args) { IPassportForThird passportForThird = new PassportForThirdAdapter(); passportForThird.loginForQQ(""); }
源码中运用:
public interface AdvisorAdapter { boolean supportsAdvice(Advice advice); MethodInterceptor getInterceptor(Advisor advisor); }
class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable { @Override public boolean supportsAdvice(Advice advice) { return (advice instanceof MethodBeforeAdvice); } @Override public MethodInterceptor getInterceptor(Advisor advisor) { MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice(); return new MethodBeforeAdviceInterceptor(advice); } }
class AfterReturningAdviceAdapter implements AdvisorAdapter, Serializable { @Override public boolean supportsAdvice(Advice advice) { return (advice instanceof AfterReturningAdvice); } @Override public MethodInterceptor getInterceptor(Advisor advisor) { AfterReturningAdvice advice = (AfterReturningAdvice) advisor.getAdvice(); return new AfterReturningAdviceInterceptor(advice); } }
class ThrowsAdviceAdapter implements AdvisorAdapter, Serializable { @Override public boolean supportsAdvice(Advice advice) { return (advice instanceof ThrowsAdvice); } @Override public MethodInterceptor getInterceptor(Advisor advisor) { return new ThrowsAdviceInterceptor(advisor.getAdvice()); } }
public class SimpleControllerHandlerAdapter implements HandlerAdapter { @Override public boolean supports(Object handler) { return (handler instanceof Controller); } @Override @Nullable public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return ((Controller) handler).handleRequest(request, response); } @Override public long getLastModified(HttpServletRequest request, Object handler) { if (handler instanceof LastModified) { return ((LastModified) handler).getLastModified(request); } return -1L; } }
AbstractHandlerMethodAdapter @Override public final boolean supports(Object handler) { return (handler instanceof HandlerMethod && supportsInternal((HandlerMethod) handler)); }
class CompositeHandlerAdapter implements HandlerAdapter { private final ListableBeanFactory beanFactory; private List<HandlerAdapter> adapters; CompositeHandlerAdapter(ListableBeanFactory beanFactory) { this.beanFactory = beanFactory; } @Override public boolean supports(Object handler) { return getAdapter(handler).isPresent(); } @Override public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { Optional<HandlerAdapter> adapter = getAdapter(handler); if (adapter.isPresent()) { return adapter.get().handle(request, response, handler); } return null; } @Override public long getLastModified(HttpServletRequest request, Object handler) { Optional<HandlerAdapter> adapter = getAdapter(handler); if (adapter.isPresent()) { return adapter.get().getLastModified(request, handler); } return 0; } private Optional<HandlerAdapter> getAdapter(Object handler) { if (this.adapters == null) { this.adapters = extractAdapters(); } return this.adapters.stream().filter((a) -> a.supports(handler)).findFirst(); } private List<HandlerAdapter> extractAdapters() { List<HandlerAdapter> list = new ArrayList<>(); list.addAll(this.beanFactory.getBeansOfType(HandlerAdapter.class).values()); list.remove(this); AnnotationAwareOrderComparator.sort(list); return list; } }
public class HttpRequestHandlerAdapter implements HandlerAdapter { @Override public boolean supports(Object handler) { return (handler instanceof HttpRequestHandler); } @Override @Nullable public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { ((HttpRequestHandler) handler).handleRequest(request, response); return null; } @Override public long getLastModified(HttpServletRequest request, Object handler) { if (handler instanceof LastModified) { return ((LastModified) handler).getLastModified(request); } return -1L; } }
public class SimpleServletHandlerAdapter implements HandlerAdapter { @Override public boolean supports(Object handler) { return (handler instanceof Servlet); } @Override @Nullable public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { ((Servlet) handler).service(request, response); return null; } @Override public long getLastModified(HttpServletRequest request, Object handler) { return -1; } }