美文网首页
适配器模式在实际生产中的应用示例 - 多种登录方式使用同一入口

适配器模式在实际生产中的应用示例 - 多种登录方式使用同一入口

作者: 王跃琅 | 来源:发表于2022-08-12 09:24 被阅读0次

工作中我们经常会遇到同一入口处理多种逻辑的情况,有很多小伙伴会直接像下面这样使用面板模式进行if…else…的判断,来进入不同的处理逻辑:

@RequestMapping("/login")
public Response login(@RequestBody LoginParam loginParam){
    if(Constant.PASSWORD.equals(loginParam.getLoginType())){
        // 密码登录逻辑处理;
    }else if(Constant.SMS_CODE.equals(loginParam.getLoginType())){
        // 验证码登录逻辑处理;
    }else if(……){……}
    ……
}

这样的代码效率慢就不说了,毕竟也慢不到哪去,但是看起来就不美观,而且每次增加一种登录方式,就需要在这个方法中加一个else if。
那么如何让代码更加优雅呢?这就不得不用到设计模式了。下面就用适配器模式来演示一下如何实现。

  1. 声明一个BaseService,声明我们Service需要具备的基本功能:
public interface BaseService<T> {
    /**
     * 获取编码
     */
    String getTrackCode();

    /**
     * 处理
     * @param param 登录参数
     */
    void handle(T param) throws Exception;
}

getTraceCode()方法用来获取当前Service的唯一标识,handle()方法处理业务逻辑。

  1. 声明一个Service标识的字典:
public class RouteNodeDictionary {

    /**
     * 密码登录
     */
    public static final String PASSWORD_LOGIN = "PASSWORD_LOGIN";

    /**
     * 验证码登录
     */
    public static final String SMS_CODE_LOGIN = "SMS_CODE_LOGIN";
}
  1. 再声明一个抽象类,实现BaseService接口:
public abstract class AbstractLoginService<T> extends BaseServiceAdapter<T> {

    @Override
    public void handle(T param) throws Exception {
        //实现handle接口 完善登录流程  具体实现交由子类
        login(param);
    }

    /**
     * 登录
     * @param param 登录参数
     */
    abstract void login(T param) throws Exception;
}

抛出的异常可以自定义一个异常类,只要处理请求不是按正常逻辑走的,统统抛出异常,在Controller层进行处理就好了。

  1. 马上就完成了,然后就是写我们真正的实现类:
public class LoginByPasswordService extends AbstractLoginService<LoginByPasswordRequestParam> {
    @Override
    void login(LoginByPasswordRequestParamparam) throws Exception {
        // 密码登录逻辑处理;
    }

    @Override
    public String getTrackCode() {
        return RouteNodeDictionary.PASSWORD_LOGIN;
    }
}
  1. 最后,在Controller层对Service进行注册和获取,写法如下:
public class LoginController {

    private final Map<String, BaseService> serviceMap = new HashMap<>();

    @Autowired
    public void setServices(List<BaseService> services) {
        services.forEach(service -> serviceMap.put(service. getTrackCode(), service));
    }

    @RequestMapping("/login")
    public Response login(@RequestBody LoginParam param) {
        try {
            services.get(param.getLoginType()).handle(param);
            return Response.ok();
        } catch (Exception e) {
            return Response.error(e.getErrorEnums());
        }
    }
}

大功告成!看起来试复杂了很多,但是写起来就爽很多了,希望大家都能感受到设计模式的好处,我也要去学习了,拜拜。

相关文章

网友评论

      本文标题:适配器模式在实际生产中的应用示例 - 多种登录方式使用同一入口

      本文链接:https://www.haomeiwen.com/subject/rdkvbrtx.html