Spring中常見的設計模式——適配器模式


一、適配器模式的應用場景  

  適配器模式(Adapter Pattern)是指將一個類的接口轉換成用戶期待的另一個接口,使原本接口不兼容的類可以一起工作,屬於構造設計模式。

  適配器適用於以下幾種業務場景:

  • 已經存在的類的方法和需求不匹配(方法結果相同或相似)的情況。
  • 適配器模式不是軟件初始階段應該考慮的設計模式,是隨着軟件的開發,由於不同產品、不同廠家造成功能類似而接口不同的問題的解決方案,有點亡羊補牢的感覺。

二、重構第三方登錄自由適配的業務場景

  將原來的單一支持用戶名和密碼登錄,擴展為可以支持微信和手機登錄。

  創建統一返回結果ResultMsg:

復制代碼
@Data
public class ResultMsg {
private Integer code;
private String msg;
private Object data;

public ResultMsg(Integer code, String msg, Object data) {
this.code = code;
this.data = data;
this.msg = msg;
}
}
復制代碼

  老系統登錄代碼如下:

復制代碼
public class SignInService {
    public ResultMsg regist(String userName, String passWord) {
        return new ResultMsg(200, "注冊成功", new Member());
    }

    public ResultMsg login(String userName, String passWord) {
        return null;
    }
}
復制代碼

  為了遵循開閉原則,我們不修改老系統代碼,下面是Member類:

復制代碼
@Data
public class Member {
    private String userName;
    private String passWord;
    private String mid;
    private String info;
}
復制代碼

  我們優雅的根據不同登錄方式創建不同的“Adapter”,首先創建LoginAdapter:

復制代碼
public interface LoginAdapter {
    boolean support(Object adapter);

    ResultMsg login(String id, Object adapter);
}
復制代碼

  手機登錄:

復制代碼
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 LoginForWechatAdapter implements LoginAdapter {
    @Override
    public boolean support(Object adapter) {
        return adapter instanceof LoginForWechatAdapter;
    }

    @Override
    public ResultMsg login(String id, Object adapter) {
        return null;
    }
}
復制代碼

  接着,創建第三方登錄兼容接口IPassportForThid:

復制代碼
public interface IPassportForThird {
    ResultMsg loginForTel(String telephone, String code);

    ResultMsg loginForWechat(String id);

    ResultMsg loginForResist(String userName, String passWord);
}
復制代碼

  實現兼容PassportForThirdAdapter:

復制代碼
public class PassportForThirdAdapter extends SignInService implements IPassportForThird {
    @Override
    public ResultMsg loginForTel(String telephone, String code) {
        return null;
    }

    @Override
    public ResultMsg loginForWechat(String id) {
        return null;
    }

    @Override
    public ResultMsg loginForResist(String userName, String passWord) {
        super.regist(userName, passWord);
        return super.login(userName, passWord);
    }

    //這里使用簡單工廠及策略模式
    private ResultMsg procssLogin(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;
    }
}
復制代碼

  前面每個適配器都加上了support()方法,用來判斷箭筒。support()方法的參數也是Object類型,而support()來自接口。適配器並不依賴接口,我們使用接口只是為了代碼規范。

三、適配器模式在源碼中的體現

  Spring中的AOP中AdvisorAdapter類,它有三個實現:MethodBeforAdviceAdapter、AfterReturnningAdviceAdapter、ThrowsAdviceAdapter。

  先看頂層接口AdviceAdapter的源代碼:

復制代碼
public interface AdvisorAdapter {
    boolean supportsAdvice(Advice var1);

    MethodInterceptor getInterceptor(Advisor var1);
}
復制代碼

  再看MethodBeforAdviceAdapter:

復制代碼
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable {
    private final MethodBeforeAdvice advice;

    public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
        Assert.notNull(advice, "Advice must not be null");
        this.advice = advice;
    }

    public Object invoke(MethodInvocation mi) throws Throwable {
        this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
        return mi.proceed();
    }
}
復制代碼

  其他兩個類就不看了。Spring會根據不同的AOP配置來使用對應的“Advice”,與策略模式不同的是,一個方法可以同時擁有多個“Advice”。

四、適配器模式的優缺點

  優點:

  • 能提高類的透明性和復用性,現有的類會被復用但不需要改變。
  • 目標類和適配器類解耦,可以提高程序的擴展性。
  • 在很多業務場景中符合開閉原則。

  缺點:

  • 在適配器代碼編寫過程中需要進行全面考慮,可能會增加系統復雜度。
  • 增加代碼閱讀難度,過多使用適配器會使系統代碼變得凌亂。

轉載於:https://www.cnblogs.com/xcgShare/p/12190642.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM