对接多种三方的设计模式_死磕设计模式之适配器模式
適配器模式
定義
?適配器模式(Adapter Pattern)是指將一個(gè)類的接口轉(zhuǎn)換成客戶期望的另一個(gè)接口,使原本的接口不兼容的類可以一起工作,屬于結(jié)構(gòu)型設(shè)計(jì)模式。
適用場(chǎng)景
1、已經(jīng)存在的類,它的方法和需求不匹配(方法結(jié)果相同或相似)的情況。
2、適配器模式不是軟件設(shè)計(jì)階段考慮的設(shè)計(jì)模式,是隨著軟件維護(hù),由于不同產(chǎn)品、不同廠家造成功能類似而接口不相同情況下的解決方案。有點(diǎn)亡羊補(bǔ)牢的感覺。
實(shí)例
我們現(xiàn)在的登錄有很多種,QQ、微信等,我們利用適配模式來寫下這個(gè)代碼
創(chuàng)建統(tǒng)一的返回結(jié)果類
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; }}我們假設(shè)原來的系統(tǒng)的登錄邏輯是SinginService
public class SiginService {/** * 注冊(cè)方法 * @param username * @param password * @return */public ResultMsg regist(String username,String password){return new ResultMsg(200,"注冊(cè)成功",new Member()); }/** * 登錄的方法 * @param username * @param password * @return */public ResultMsg login(String username,String password){return null; }}創(chuàng)建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; }}原來的邏輯代碼我們不動(dòng),新創(chuàng)建一個(gè)類繼承
public class SinginForThirdService extends SiginService {public ResultMsg loginForQQ(String openId){//1、openId是全局唯一,我們可以把它當(dāng)做是一個(gè)用戶名(加長)//2、密碼默認(rèn)為QQ_EMPTY//3、注冊(cè)(在原有系統(tǒng)里面創(chuàng)建一個(gè)用戶)//4、調(diào)用原來的登錄方法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); }}客戶端測(cè)試代碼
public static void main(String[] args) { SinginForThirdService service = new SinginForThirdService(); service.login("tom","123456"); service.loginForQQ("sdfasdfasf"); service.loginForWechat("sdfasfsa"); }通過一個(gè)簡單的適配,完成了代碼的兼容?。當(dāng)然我們的代碼還可以優(yōu)化,很多人可能想到了策略模式,工廠模式?。我們下面來優(yōu)化下
根據(jù)不同的登錄方式,創(chuàng)建不同的Adapter,首先創(chuàng)建LoginAdapter
public interface LoginAdapter {boolean support(Object adapter); ResultMsg login(String id,Object adapter);}分別實(shí)現(xiàn)不同的登錄適配,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; }}然后創(chuàng)建第三方登錄兼容接口
public interface IPassportForThird {/** * QQ登錄 * @param id * @return */ResultMsg loginForQQ(String id);/** * 微信登錄 * @param id * @return */ResultMsg loginForWechat(String id);/** * 記住登錄狀態(tài)后自動(dòng)登錄 * @param token * @return */ResultMsg loginForToken(String token);/** * 手機(jī)號(hào)登錄 * @param telphone * @param code * @return */ResultMsg loginForTelphone(String telphone, String code);/** * 注冊(cè)后自動(dòng)登錄 * @param username * @param passport * @return */ResultMsg loginForRegist(String username, String passport);}實(shí)現(xiàn)兼容類
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{//適配器不一定要實(shí)現(xiàn)接口 LoginAdapter adapter = clazz.newInstance();//判斷傳過來的適配器是否能處理指定的邏輯if(adapter.support(adapter)){return adapter.login(key,adapter); } }catch (Exception e){ e.printStackTrace(); }return null;????}}客戶端測(cè)試代碼
public class PassportTest {public static void main(String[] args) { IPassportForThird passportForThird = new PassportForThirdAdapter();????????passportForThird.loginForQQ(""); }}看下類圖
優(yōu)點(diǎn)
1、能提高類的透明性和復(fù)用,現(xiàn)有的類復(fù)用但不需要改變。
2、目標(biāo)類和適配器類解耦,提高程序的擴(kuò)展性。
3、在很多業(yè)務(wù)場(chǎng)景中符合開閉原則。
?
缺點(diǎn)
1、適配器編寫過程需要全面考慮,可能會(huì)增加系統(tǒng)的復(fù)雜性。
2、增加代碼閱讀難度,降低代碼可讀性,過多使用適配器會(huì)使系統(tǒng)代碼變得凌亂。
總結(jié)
以上是生活随笔為你收集整理的对接多种三方的设计模式_死磕设计模式之适配器模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python画图如何调整图例位置_mat
- 下一篇: 抽象方法可以有方法体_抽象类和模板方法设