適配器模式(Adapter Pattern)是指將一個類的接口轉換成客戶指望的另外一個接口,使本來的接口不兼容的類能夠一塊兒工做。設計模式
屬於結構型設計模式微信
適用場景: 1 已經存在的類,它的方法和需求不匹配(方法結果相同或類似)的狀況ide
2 適配器模式不是軟件設計階段考慮的設計模式,是隨着軟件維護,因爲不一樣產品、不一樣廠家形成功能相似而接口不相同狀況下的解決方案this
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 目標類和適配器類解耦,提升程序的擴展性code
3 在不少業務場景中符合開閉原則blog
缺點: 1 適配器編寫過程須要全面考慮,可能會增長系統的複雜性token
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) { //一、openId是全局惟一,咱們能夠把它當作是一個用戶名(加長) //二、密碼默認爲QQ_EMPTY //三、註冊(在原有系統裏面建立一個用戶) //四、調用原來的登陸方法 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"); }
工廠、策略、適配器:rem
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; } }