java用户的登录图片_Java多态--用户登录方式角度看

Java多态的定义我就不说了,今天用用户登录的案例来讲解多态。

用户登录功能是交互系统中的必不可少的一个功能。

登录方式有以下几种

  1. 用户名+密码
  2. 用户名+验证码
  3. 手机号+密码
  4. 手机号+验证码

数据传输的格式是:

public class LoginUser {
    private String username;  // 用户名
    private String password; // 密码
    private String mobile; // 手机号
    private String code;  // 验证码
    // 忽略getter setter
}
  1. if判断的方式

使用if判断是最简单也是最容易想到的方式,按照步骤一步一步的操作,这是一种面向过程的思维(本人对面向过程,面向对象,函数式编程没有偏见,他们都是为了解决问题的)。这种方式如果判断条件少时,阅读起来通俗易懂;但是,条件多时,就不那么好阅读了。

if (Objects.nonNull(user.getUsername()) && Objects
                .nonNull(user.getPassword())) {
    // 用户名+密码
    User user1 = userService.findByUsername(user.getUsername());
    if (Objects.equals(user1.getPassword(), user.getPassword())) {
        return user1;
    }
    throw new RuntimeException("密码不正确");
} else if (Objects.nonNull(user.getUsername()) && Objects
        .nonNull(user.getCode())) {
    // 用户名+验证码
    User user1 = userService.findByUsername(user.getUsername());
    if (codeService.codeCheck(user.getCode())) {
        return user1;
    }
    throw new RuntimeException("验证码不正确");
} else if (Objects.nonNull(user.getMobile()) && Objects
        .nonNull(user.getPassword())) {
    // 手机号+密码
    User user1 = userService.findByMobile(user.getMobile());
    if (Objects.equals(user1.getPassword(), user.getPassword())) {
        return user1;
    }
    throw new RuntimeException("密码不正确");
} else if (Objects.nonNull(user.getMobile()) && Objects
        .nonNull(user.getCode())) {
    // 手机号+验证码
    User user1 = userService.findByMobile(user.getMobile());
    if (codeService.codeCheck(user.getCode())) {
        return user1;
    }
    throw new RuntimeException("验证码不正确");
} else {
    throw new RuntimeException("组合不正确");
}

2. 判定表的方式

判定表的方式是对if判断的一个改善,不再使用if判断,而是使用类似于条件矩阵的方式来判定,好处是当条件比较多时,也容易阅读(一般一个函数中的代码不要超过40行,这样的话,可以在一屏中全部阅读整个函数,对于阅读者更加容易掌控理解)。

判定表源码:https://github.com/wenyu7980/decisiontable

public class DecisionTableLoginHandler implements LoginHandler {
    private final DecisionTable<Function<LoginUser, User>> DECISIONS = DecisionTable
            .of();

    @Autowired
    private UserService userService;
    @Autowired
    private CodeService codeService;

    public DecisionTableLoginHandler() {
        // 用户名 手机号 密码 验证码
        DECISIONS.add(this::userPasswd, NOT_NULL(), ANY(), NOT_NULL(), ANY());
        DECISIONS.add(this::userCode, NOT_NULL(), NULL(), NULL(), NOT_NULL());
        DECISIONS
                .add(this::mobilePasswd, NULL(), NOT_NULL(), NOT_NULL(), ANY());
        DECISIONS.add(this::mobileCode, NULL(), NOT_NULL(), NULL(), NOT_NULL());
    }

    @Override
    public User login(LoginUser user) {
        Function<LoginUser, User> function = DECISIONS
                .get(user.getUsername(), user.getMobile(), user.getPassword(),
                        user.getCode())
                .orElseThrow(() -> new RuntimeException("组合不正确"));
        return function.apply(user);
    }

    private User userPasswd(LoginUser user) {
        // 用户名+密码
        User user1 = userService.findByUsername(user.getUsername());
        if (Objects.equals(user1.getPassword(), user.getPassword())) {
            return user1;
        }
        throw new RuntimeException("密码不正确");
    }

    private User userCode(LoginUser user) {
        // 用户名+验证码
        User user1 = userService.findByUsername(user.getUsername());
        if (codeService.codeCheck(user.getCode())) {
            return user1;
        }
        throw new RuntimeException("验证码不正确");
    }

    private User mobilePasswd(LoginUser user) {
        // 手机号+密码
        User user1 = userService.findByMobile(user.getMobile());
        if (Objects.equals(user1.getPassword(), user.getPassword())) {
            return user1;
        }
        throw new RuntimeException("密码不正确");
    }

    private User mobileCode(LoginUser user) {
        // 手机号+验证码
        User user1 = userService.findByMobile(user.getMobile());
        if (codeService.codeCheck(user.getCode())) {
            return user1;
        }
        throw new RuntimeException("验证码不正确");
    }
}

3.面向接口的方式

这种方式是把判定表和面向接口编程进行整合,好处是,条件和业务是内聚到一个文件中,如果需要增减条件判断情况,只需要增减接口实现类就行,不要更改其他文件,使逻辑解耦(高内聚,低耦合)。但是缺点也很明显,如果对这种结构不了解的话,阅读起来会很费劲。

public interface LoginComponent {
    User login(LoginUser user);

    default Decision username() {
        return NULL();
    }

    default Decision password() {
        return NULL();
    }

    default Decision mobile() {
        return NULL();
    }

    default Decision code() {
        return NULL();
    }
}

fb297d536811e332a63089e3e3952400.png

以上三种方式。

总结:

三种方式没有优劣,看情境而定。逻辑简单用if,变更大用面向接口。

代码:

wenyu7980/UserLoginSample

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值