服务层和控制器中的代码分离
Code Separation in Service Layer and Controller
我已经编写了重置密码和应用程序其他部分的代码,
我想将服务层与 dao 和控制器分开;
我的控制器代码是:
@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);
}
我对将代码移动到服务层感到困惑;上面的方法是正确的还是必须将一些代码(例如下面的代码)移到服务层?如果我将这段代码移到服务层,我怎样才能得到响应?布尔值(不可接受,因为我想 return 更正给用户的消息),字符串或异常?;
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);
}
MVS 只是一种简化,并不是一种完美的方法。这就是为什么它提出了这么多与此类似的问题。
- 控制器中应包含多少逻辑?
- 模型应该包含任何逻辑吗?
- 视图是否应该包含逻辑?
像这样的问题很难回答,但控制器可以验证输入并在需要时重定向到视图。您的代码看起来确实很像域逻辑,稍后应该将其放入服务中,但显然在您的控制器中更容易管理。对于领域逻辑(又名业务逻辑、业务规则和领域知识),我们可以将其解释为做出关键业务决策的逻辑。
所以,没错,您是在控制器中做出决定,但在服务中管理这些决定会使解决方案复杂化。所以,我就把它留在那里,无论如何最后,除了你和你的团队之外,没有人会为这段代码做出贡献,所以如果你对它感到满意,那很好。
但是,如果您要移动代码,我建议您使用异常。在我看来,服务应该只是 return 所需的模型或资源。更好地使用异常处理错误。
我已经编写了重置密码和应用程序其他部分的代码, 我想将服务层与 dao 和控制器分开; 我的控制器代码是:
@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);
}
我对将代码移动到服务层感到困惑;上面的方法是正确的还是必须将一些代码(例如下面的代码)移到服务层?如果我将这段代码移到服务层,我怎样才能得到响应?布尔值(不可接受,因为我想 return 更正给用户的消息),字符串或异常?;
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);
}
MVS 只是一种简化,并不是一种完美的方法。这就是为什么它提出了这么多与此类似的问题。
- 控制器中应包含多少逻辑?
- 模型应该包含任何逻辑吗?
- 视图是否应该包含逻辑?
像这样的问题很难回答,但控制器可以验证输入并在需要时重定向到视图。您的代码看起来确实很像域逻辑,稍后应该将其放入服务中,但显然在您的控制器中更容易管理。对于领域逻辑(又名业务逻辑、业务规则和领域知识),我们可以将其解释为做出关键业务决策的逻辑。
所以,没错,您是在控制器中做出决定,但在服务中管理这些决定会使解决方案复杂化。所以,我就把它留在那里,无论如何最后,除了你和你的团队之外,没有人会为这段代码做出贡献,所以如果你对它感到满意,那很好。
但是,如果您要移动代码,我建议您使用异常。在我看来,服务应该只是 return 所需的模型或资源。更好地使用异常处理错误。