目录
1. 概述
以用户登陆功能,来演示如何使用策略模式,来处理多种登陆方式(用户名+密码、手机号+验证码、指纹登陆等)
策略模式遵循的原则:“对修改关闭,对扩展开放的”
对登陆方式loginType作判断, 分别有不同的登陆方法来处登陆逻辑。
if(loginType==1){
//密码登录
result= loginService.loginByPassword(username,content);
}else if(loginType==2){
//手机验证码登录
result=loginService.loginBySMS(username,content);
}
Result loginBySMS(String username, String smsCode);
Result loginByPassword(String userName, String password);
不同的登陆方法中逻辑代码重复且独立。
2. 第一次重构
将逻辑相同的代码剥离出来,并且封装成不同的方法,供loginBySMS()和loginByPassword()调用。例如剥离出如下3个方法。
// step.1 检查用户状态
checkUserStatus(userInfo);
//step.2 登陆失败处理
loginFail(userInfo);
//step.3 密码正确后返回用户信息和登录的token
result=loginSuccess(userInfo);
场景变化,现在需要新增加一种登陆方式,指纹登陆,这时候Controller中的登陆逻辑判断就变成了下面的方式。
if(loginType==1){
//密码登录
result= loginService.loginByPassword(username,content);
}else if(loginType==2){
//手机验证码登录
result=loginService.loginBySMS(username,content);
} else if (loginType == 3) {
// 新增了指纹登陆方式
result = loginService.loginByGesture(userName, content);
}
经过上面的判断知道,每当新增一种登陆模式时,都需要修改LoginContreller、LoginService中的代码。并且都需要对整个登陆功能重新测一遍。
而好的代码原则是“对修改关闭,对扩展开放的”。
3. 第2次重构,使用策略模式
因为 if(){} , else if(){}本身就是一种策略逻辑,凡是使用这种if(){},else if(){}逻辑的地方都可以使用策略模式代替。
4. 第3次重构
在策略模式的基础上,加入模板模式
上述每种策略处理模式中,都有相同的逻辑代码,他们判断登陆的流程都是一行的:
1、首先我们先查询用户信息。
2、验证用户状态。
3、根据登录类型验证对应的数据,返回是否登录成功。
4、登录成功则生成token返回数据,登录失败时则记录错误次数。
有一种设计模式是专门定义流程,复用重复功能的模式叫“模板模式”。
5. 参考资料
https://zhuanlan.zhihu.com/p/157633600
代码gitee地址:参考这里