I have a Service
and a Controller
.
Each method in the service its preconditions , for example :
public void doSomething(Parameter para1 , Parameter para2 ...) {
if ( something wrong ) {
throw new RuntimeException1();
}
if ( another thing wrong ) {
throw new RuntimeException2();
}
// continue do something
}
And in the Controller layer , there are two methods , one is showForm()
which displays form for user to input ; another is doApplyForm()
which accepts form and calls the underlaying Service.doSomething()
.
The following is the pseudo code (I eliminated some BindingResult
, attr.addFlashAttribute
codes ) :
@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";
}
}
It works well , but I am not satisfied. There're bad smells within.
The problem is in the showForm()
, which shares identical preconditions with Controller.doSomething()
.
If Service.doSomething()
add another preconditions in the future , Controller.showForm()
has to do correspondent changes.
I wonder if there're any design pattern or frameworks to eliminate such bad smell ?
Java8's functional solutions are welcome.
Thanks.
You can define a util class called Preconditions
and move all your validation logic there. It's a common pattern and there are a number of frameworks that make use of it. For example, Guava: Preconditions docs.
At least like this your if (condition) throw new exception
will be capsulated and easier to manage.