在控制器和服务之间共享相同的方法前提逻辑?
Share same method precondition logic between controllers and services?
我有一个 Service
和一个 Controller
。
服务中的每个方法都有其先决条件,例如:
public void doSomething(Parameter para1 , Parameter para2 ...) {
if ( something wrong ) {
throw new RuntimeException1();
}
if ( another thing wrong ) {
throw new RuntimeException2();
}
// continue do something
}
而在Controller层,有两种方法,一种是showForm()
显示表单供用户输入;另一个是 doApplyForm()
,它接受表单并调用底层 Service.doSomething()
.
以下是伪代码(我去掉了一些BindingResult
,attr.addFlashAttribute
代码):
@Injected Service service;
public String showForm() {
if ( something wrong ) {
throw new RuntimeException1();
}
if ( another thing wrong ) {
throw new RuntimeException2();
}
return "showForm";
}
public String doApplyForm(@Validated Form form) {
try {
service.doSomething(para1 , para2 ...);
return "redirect:/";
} catch (Exception e) {
// error handling
return "redirect:/error";
}
}
效果很好,但我不满意。里面有难闻的气味。
问题出在 showForm()
中,它与 Controller.doSomething()
具有相同的先决条件。
如果以后Service.doSomething()
再增加一个先决条件,Controller.showForm()
必须做相应的改变。
不知是否有设计模式或框架可以消除这种难闻的气味?
Java8 的功能解决方案是受欢迎的。
谢谢。
您可以定义一个名为 Preconditions
的实用程序 class 并将所有验证逻辑移到那里。这是一种常见的模式,有许多框架都在使用它。例如番石榴:Preconditions docs.
至少这样你的if (condition) throw new exception
会被封装起来更容易管理
为服务请求引入一个参数对象,并将验证逻辑放入请求对象中。例如
public class DoSomethingRequest {
private Parameter param1;
private Parameter param2;
public void validate(){
if ( something wrong ) {
throw new RuntimeException1();
}
if ( another thing wrong ) {
throw new RuntimeException2();
}
}
}
您的服务会更轻松
public void doSomething(DoSomethingRequest request) {
request.validate();
}
所以控制器
public String showForm() {
DoSomethingRequest request = ... // obtained somehow
request.validate();
// ...
return "showForm";
}
这将服务方法的前提条件封装在一个对象中。
我有一个 Service
和一个 Controller
。
服务中的每个方法都有其先决条件,例如:
public void doSomething(Parameter para1 , Parameter para2 ...) {
if ( something wrong ) {
throw new RuntimeException1();
}
if ( another thing wrong ) {
throw new RuntimeException2();
}
// continue do something
}
而在Controller层,有两种方法,一种是showForm()
显示表单供用户输入;另一个是 doApplyForm()
,它接受表单并调用底层 Service.doSomething()
.
以下是伪代码(我去掉了一些BindingResult
,attr.addFlashAttribute
代码):
@Injected Service service;
public String showForm() {
if ( something wrong ) {
throw new RuntimeException1();
}
if ( another thing wrong ) {
throw new RuntimeException2();
}
return "showForm";
}
public String doApplyForm(@Validated Form form) {
try {
service.doSomething(para1 , para2 ...);
return "redirect:/";
} catch (Exception e) {
// error handling
return "redirect:/error";
}
}
效果很好,但我不满意。里面有难闻的气味。
问题出在 showForm()
中,它与 Controller.doSomething()
具有相同的先决条件。
如果以后Service.doSomething()
再增加一个先决条件,Controller.showForm()
必须做相应的改变。
不知是否有设计模式或框架可以消除这种难闻的气味?
Java8 的功能解决方案是受欢迎的。
谢谢。
您可以定义一个名为 Preconditions
的实用程序 class 并将所有验证逻辑移到那里。这是一种常见的模式,有许多框架都在使用它。例如番石榴:Preconditions docs.
至少这样你的if (condition) throw new exception
会被封装起来更容易管理
为服务请求引入一个参数对象,并将验证逻辑放入请求对象中。例如
public class DoSomethingRequest {
private Parameter param1;
private Parameter param2;
public void validate(){
if ( something wrong ) {
throw new RuntimeException1();
}
if ( another thing wrong ) {
throw new RuntimeException2();
}
}
}
您的服务会更轻松
public void doSomething(DoSomethingRequest request) {
request.validate();
}
所以控制器
public String showForm() {
DoSomethingRequest request = ... // obtained somehow
request.validate();
// ...
return "showForm";
}
这将服务方法的前提条件封装在一个对象中。