适配器模式

前言:边动手,边动脑,才能进步,只动手不动脑,一塌糊涂

定义:
将一个接口转化成用户期望的另一个接口,使原本不兼容的类可以一起工作,属于结构型设计模式。

适用场景:
1.已经存在的类,它的方法和需求不匹配(方法结果相同或相似)
2.适配器模式是随着软件维护,由于不同产品,不同厂商造成功能类似而接口不相同的解决方案

实际案例
比较旧的软件登录只支持用户名和密码登录,现在在用户名和密码登录的同时多了扣扣登录、微信登录、手机登录等情况,
登录的方式变了,不过登录的结果不会变,同样将登录状态保存到session、redis等缓存中

package com.ns.adapter;

/**
 * 通用的返回类
 */
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;
    }
}

package com.ns.adapter;

/**
 * 旧的登录类
 */
public class OldLogin {

    /**
     * 注册
     */
    public ResultMsg regist(String userName, String password){
        System.out.println("注册成功");
        return new ResultMsg(200,"注册成功",null);
    }

    /**
     *  登录
     */
    public ResultMsg login(String userName, String password){
        System.out.println("用户名和密码登录成功");
        return new ResultMsg(200,"用户名和密码登录成功",null);
    }
}

package com.ns.adapter;

/**
 * 扩展新的登录方式接口,只是为了抽象出验证方法与登录方法,用来让其他登录方式实现
 */
public interface ILoginService {
    //验证方法,针对使用策略模式做一个简单验证,可以通过其他方式解决
    boolean support(Object adapter);

    ResultMsg login(String id, Object adapter);

}

package com.ns.adapter;

/**
 * QQ登录
 */
public class QQLogin implements ILoginService {
    @Override
    public boolean support(Object adapter) {
        return adapter instanceof QQLogin;
    }

    @Override
    public ResultMsg login(String id, Object adapter) {
        System.out.println("通过QQ登录");
        return new ResultMsg(200,"QQ登录成功",null);
    }
}

package com.ns.adapter;

/**
 * 微信登录
 */
public class WechatLogin implements ILoginService {
    @Override
    public boolean support(Object adapter) {
        return adapter instanceof WechatLogin;
    }

    @Override
    public ResultMsg login(String id, Object adapter) {
        System.out.println("通过微信登录");
        return new ResultMsg(200,"通过微信登录成功",null);
    }
}

package com.ns.adapter;

/**
 * 手机号登录
 */
public class TelLogin implements ILoginService {
    @Override
    public boolean support(Object adapter) {
        return adapter instanceof TelLogin;
    }

    @Override
    public ResultMsg login(String id, Object adapter) {
        System.out.println("通过手机号登录");
        return new ResultMsg(200,"通过手机号登录成功",null);
    }
}

package com.ns.adapter;

/**
 * 其他方式登录接口的集成
 * 此接口以及实现类也可以省去,根据不同的登录类型抽象出不同的策略,使用策略模式来达到不同场景的登录需求
 */
public interface LoginForOther {

    ResultMsg loginForQQ(String id);

    ResultMsg loginForWechat(String id);

    ResultMsg loginForTel(String id);

    ResultMsg loginForRegist(String userName, String password);
}

package com.ns.adapter;

/**
 *  其他方式登录接口的集成实现
 *  登录适配器类,通过集成老的登录方式,并实现新的登录方式,保证旧的保留,新的可用
 */
public class LoginForOtherAdapter extends OldLogin implements LoginForOther {
    @Override
    public ResultMsg loginForQQ(String id) {
        return processLogin(id,QQLogin.class);
    }

    @Override
    public ResultMsg loginForWechat(String id) {
        return processLogin(id,WechatLogin.class);
    }

    @Override
    public ResultMsg loginForTel(String id) {
        return processLogin(id,TelLogin.class);
    }

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

    /**
     *  简单工厂模式以及策略模式的应用
     */
    private ResultMsg processLogin(String key, Class<? extends ILoginService> clazz){
        try {
            ILoginService loginService = clazz.newInstance();
            if(loginService.support(loginService)){
                return loginService.login(key,loginService);
            }
            return null;
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }
}

package com.ns.adapter;

/**
 * 测试类
 */
public class TestLogin {
    public static void main(String[] args) {
        LoginForOther loginForOther = new LoginForOtherAdapter();
        loginForOther.loginForTel("1111");
    }
}

总结
优点:
1.提高类的透明和应用,现有类复用但不需要改变
2.目标类和适配器类解耦,提高类的可扩展性
缺点:
1.适配器编写过程需要全面考虑,会增加系统的复杂度
2.降低了代码的可读性,使代码更复杂

注:上述案例只是简单说明了适配器模式的应用,代码逻辑方面可以再次应用策略模式进行扩展,可以自己思考下。
最后,希望大家都能学以致用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值