服务层和控制器中的代码分离

时间:2018-11-10 09:41:13

标签: java spring spring-mvc dao service-layer

我已经为重置密码和应用程​​序的其他部分编写了代码, 我想将服务层与dao和controller分开; 我的控制器代码是:

@RequestMapping(value = "", method = RequestMethod.PUT)
public ResponseModel resetPassword(@Valid @RequestBody AuthenticationRequestModel authenticationRequestModel, HttpServletRequest request) {
    String ip = WebUtils.getClientIp(request);
    Optional<SecuritySMS> securitySMS = securitySMSService.getLastValidSMS(authenticationRequestModel.getMobile());
    if (!securitySMS.isPresent()) {
        return new ResponseModel(messages.get("sms.security.expired"), ResponseModel.ResponseStatus.ERROR);
    }
    SecuritySMS sms = securitySMS.get();
    if (!sms.isConfirmed()) {
        return new ResponseModel(messages.get("sms.security.expired"), ResponseModel.ResponseStatus.ERROR);
    } else if (!sms.getIp().equalsIgnoreCase(ip)) {
        return new ResponseModel(messages.get("sms.security.ip.changed"), ResponseModel.ResponseStatus.ERROR);
    }
    Optional<User> user = userService.findByMobile(sms.getMobile());
    if (!user.isPresent()) {
        return new ResponseModel(messages.get("sms.reset.user.nonexistent"), ResponseModel.ResponseStatus.ERROR);
    }

    userService.updatePassword(user.get(), authenticationRequestModel.getPassword());
    return authHelper.loginWithHttpResponse(authenticationRequestModel);
}

我对将代码移动到服务层感到困惑;上面的方法是正确的还是必须将某些代码(例如下面的代码)移到服务层?如果我将此代码移到服务层,如何获得响应?布尔值(不可接受,因为我想向用户返回正确的消息),字符串还是异常?

String ip = WebUtils.getClientIp(request);
Optional<SecuritySMS> securitySMS = securitySMSService.getLastValidSMS(authenticationRequestModel.getMobile());
if (!securitySMS.isPresent()) {
    return new ResponseModel(messages.get("sms.security.expired"), ResponseModel.ResponseStatus.ERROR);
}
SecuritySMS sms = securitySMS.get();
if (!sms.isConfirmed()) {
    return new ResponseModel(messages.get("sms.security.expired"), ResponseModel.ResponseStatus.ERROR);
} else if (!sms.getIp().equalsIgnoreCase(ip)) {
    return new ResponseModel(messages.get("sms.security.ip.changed"), ResponseModel.ResponseStatus.ERROR);
}
Optional<User> user = userService.findByMobile(sms.getMobile());
if (!user.isPresent()) {
    return new ResponseModel(messages.get("sms.reset.user.nonexistent"), ResponseModel.ResponseStatus.ERROR);
}

1 个答案:

答案 0 :(得分:1)

MVS只是一种简化,并不是一个完美的方法。这就是为什么它提出了很多与此问题类似的问题。

  • 控制器应加入多少逻辑?
  • 模型应该包含任何逻辑吗?
  • 视图应该包含逻辑吗?

这样的问题很难回答,但是控制器需要验证输入并在需要时重定向到视图。您的代码看起来很像域逻辑,应该稍后再在服务中使用,但是显然在控制器中更容易管理。对于领域逻辑(又名业务逻辑,业务规则和领域知识),我们可以将其解释为做出关键业务决策的逻辑。

因此,的确,您正在控制器中做出决策,但是在服务中管理这些决策会使解决方案复杂化。因此,无论如何,我还是将其保留在那里,最后,除了您和您​​的团队之外,没有人会为该代码做出贡献,因此,如果您对此感到满意,那就很好了。

但是,如果要移动代码,我建议使用异常。我认为服务应仅返回所需的模型或资源。更好地使用异常来处理错误。