设计模式之适配器模式(adapter)
适配器模式
不是软件设计阶段的模式,随着软件的维护造成,类或者接口不兼容的情况下衍生出适配器来处理问题
和策略模式很像,也可以理解为是策略模式的实现
策略模式专注于应用多策略,适配器专注于兼容
目标类和适配器解耦增加扩展性
提高类的复用性和透明性,现有类不需要改变
编写过程中会增加代码复杂性,难以理解
案例
多种方式登录
老版本用户密码登录服务
public class LoginService {
public void login(String username,String password){
System.out.println("使用username+password登录");
}
}
第三方登录接口
public interface ILoginForThird {
void QQLogin(String openid);
void wechatLogin(String openid);
void phoneLogin(String phone,String code);
}
适配器接口
/**
* 适配器模式,可以不用接口
* 这里只是模拟真实场景
*/
public interface LoginAdapter {
boolean supports(LoginAdapter adapter);
void login(LoginAdapter adapter, Map<String,Object> loginParam);
}
适配器实现
// 手机登录适配器
public class PhoneLoginAdapter implements LoginAdapter{
@Override
public boolean supports(LoginAdapter adapter) {
return adapter instanceof PhoneLoginAdapter;
}
@Override
public void login(LoginAdapter adapter, Map<String, Object> loginParam) {
login((String) loginParam.get("phone"), (String) loginParam.get("code"));
}
private void login(String phone,String code){
System.out.println("使用手机 - phone="+phone+"&code="+code+"登录");
}
}
// QQ登录适配器
public class QQLoginAdapter implements LoginAdapter{
@Override
public boolean supports(LoginAdapter adapter) {
return adapter instanceof QQLoginAdapter;
}
@Override
public void login(LoginAdapter adapter, Map<String, Object> loginParam) {
login((String) loginParam.get("openid"));
}
private void login(String openid){
System.out.println("使用QQ - openid="+openid+"登录");
}
}
// 微信登录适配器
public class WechatLoginAdapter implements LoginAdapter{
@Override
public boolean supports(LoginAdapter adapter) {
return adapter instanceof WechatLoginAdapter;
}
@Override
public void login(LoginAdapter adapter, Map<String, Object> loginParam) {
login((String) loginParam.get("openid"));
}
private void login(String openid){
System.out.println("使用WECHAT - openid="+openid+"登录");
}
}
第三方登陆实现
public class LoginForThirdAdapter extends LoginService implements ILoginForThird {
@Override
public void QQLogin(String openid) {
Map<String,Object> loginParam = new HashMap<>();
loginParam.put("openid",openid);
// 策略模式
processLogin(loginParam,QQLoginAdapter.class);
}
@Override
public void wechatLogin(String openid) {
Map<String,Object> loginParam = new HashMap<>();
loginParam.put("openid",openid);
processLogin(loginParam, WechatLoginAdapter.class);
}
@Override
public void phoneLogin(String phone, String code) {
Map<String,Object> loginParam = new HashMap<>();
loginParam.put("phone",phone);
loginParam.put("code",code);
processLogin(loginParam, PhoneLoginAdapter.class);
}
// 简单工厂模式
private void processLogin(Map<String,Object> loginParam , Class<? extends LoginAdapter> clazz){
try {
LoginAdapter loginAdapter = clazz.newInstance();
if (loginAdapter.supports(loginAdapter)){
loginAdapter.login(loginAdapter,loginParam);
}
}catch (Exception e){
e.printStackTrace();
}
}
}
Main
public class Main {
public static void main(String[] args) {
LoginForThirdAdapter adapter = new LoginForThirdAdapter();
// 兼容老版本登录
adapter.login("bl3air","12343");
// 支持新版本
adapter.wechatLogin("12334");
adapter.QQLogin("12334");
adapter.phoneLogin("11111111","423122");
}
}
使用username+password登录
使用WECHAT - openid=12334登录
使用QQ - openid=12334登录
使用手机 - phone=11111111&code=423122登录
应用
spring aop 通知(AdvisorAdapter)
spring mvc HandleAdapter
设计模式之适配器模式(adapter)
https://www.blaaair.com/archives/she-ji-mo-shi-zhi-shi-pei-qi-mo-shi-adapter