对接多种三方的设计模式_死磕设计模式之适配器模式
適配器模式
定義
?適配器模式(Adapter Pattern)是指將一個類的接口轉換成客戶期望的另一個接口,使原本的接口不兼容的類可以一起工作,屬于結構型設計模式。
適用場景
1、已經存在的類,它的方法和需求不匹配(方法結果相同或相似)的情況。
2、適配器模式不是軟件設計階段考慮的設計模式,是隨著軟件維護,由于不同產品、不同廠家造成功能類似而接口不相同情況下的解決方案。有點亡羊補牢的感覺。
實例
我們現在的登錄有很多種,QQ、微信等,我們利用適配模式來寫下這個代碼
創建統一的返回結果類
public class ResultMsg {private int code;private String msg;private Object data;public ResultMsg(int code, String msg, Object data) {this.code = code;this.msg = msg;this.data = data; }public int getCode() {return code; }public void setCode(int code) {this.code = code; }public String getMsg() {return msg; }public void setMsg(String msg) {this.msg = msg; }public Object getData() {return data; }public void setData(Object data) {this.data = data; }}我們假設原來的系統的登錄邏輯是SinginService
public class SiginService {/** * 注冊方法 * @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; }}創建Member類
public class Member {private String username;private String password;private String mid;private String info;public String getUsername() {return username; }public void setUsername(String username) {this.username = username; }public String getPassword() {return password; }public void setPassword(String password) {this.password = password; }public String getMid() {return mid; }public void setMid(String mid) {this.mid = mid; }public String getInfo() {return info; }public void setInfo(String info) {this.info = info; }}原來的邏輯代碼我們不動,新創建一個類繼承
public class SinginForThirdService extends SiginService {public ResultMsg loginForQQ(String openId){//1、openId是全局唯一,我們可以把它當做是一個用戶名(加長)//2、密碼默認為QQ_EMPTY//3、注冊(在原有系統里面創建一個用戶)//4、調用原來的登錄方法return loginForRegist(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 loginForRegist(String username,String password){super.regist(username,null);return super.login(username,null); }}客戶端測試代碼
public static void main(String[] args) { SinginForThirdService service = new SinginForThirdService(); service.login("tom","123456"); service.loginForQQ("sdfasdfasf"); service.loginForWechat("sdfasfsa"); }通過一個簡單的適配,完成了代碼的兼容?。當然我們的代碼還可以優化,很多人可能想到了策略模式,工廠模式?。我們下面來優化下
根據不同的登錄方式,創建不同的Adapter,首先創建LoginAdapter
public interface LoginAdapter {boolean support(Object adapter); ResultMsg login(String id,Object adapter);}分別實現不同的登錄適配,QQ登錄LoginForQQAdapter
public class LoginForQQAdapter implements LoginAdapter {public boolean support(Object adapter) {return adapter instanceof LoginForQQAdapter; }public ResultMsg login(String id, Object adapter) {return null; }}同理,其他的登錄也是一樣,我直接上代碼
public class LoginForSinaAdapter implements LoginAdapter {public boolean support(Object adapter) {return adapter instanceof LoginForSinaAdapter; }public ResultMsg login(String id, Object adapter) {return null; }}public class LoginForTelAdapter implements LoginAdapter {public boolean support(Object adapter) {return adapter instanceof LoginForTelAdapter; }public ResultMsg login(String id, Object adapter) {return null; }}public class LoginForTokenAdapter implements LoginAdapter {public boolean support(Object adapter) {return adapter instanceof LoginForTokenAdapter; }public ResultMsg login(String id, Object adapter) {return null; }}public class LoginForWechatAdapter implements LoginAdapter {public boolean support(Object adapter) {return adapter instanceof LoginForWechatAdapter; }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);}實現兼容類
public class PassportForThirdAdapter extends SiginService implements IPassportForThird {public ResultMsg loginForQQ(String id) {// return processLogin(id,RegistForQQAdapter.class);return processLogin(id,LoginForQQAdapter.class); }public ResultMsg loginForWechat(String id) {return processLogin(id,LoginForWechatAdapter.class); }public ResultMsg loginForToken(String token) {return processLogin(token,LoginForTokenAdapter.class); }public ResultMsg loginForTelphone(String telphone, String code) {return processLogin(telphone,LoginForTelAdapter.class); }public ResultMsg loginForRegist(String username, String passport) {super.regist(username,passport);return super.login(username,passport); }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 class PassportTest {public static void main(String[] args) { IPassportForThird passportForThird = new PassportForThirdAdapter();????????passportForThird.loginForQQ(""); }}看下類圖
優點
1、能提高類的透明性和復用,現有的類復用但不需要改變。
2、目標類和適配器類解耦,提高程序的擴展性。
3、在很多業務場景中符合開閉原則。
?
缺點
1、適配器編寫過程需要全面考慮,可能會增加系統的復雜性。
2、增加代碼閱讀難度,降低代碼可讀性,過多使用適配器會使系統代碼變得凌亂。
總結
以上是生活随笔為你收集整理的对接多种三方的设计模式_死磕设计模式之适配器模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python画图如何调整图例位置_mat
- 下一篇: 给国外留学的孩子汇款怎样汇