Most often I need to call a service method from a controller, and based on the outcome, if there's an error show an appropriate error message depending on the error (or some other action, showing message is just an example), otherwise proceed.
A very simple way I am using is returning an Outcome object from such method calls. Something like these:
public interface Outcome {
boolean success();
String error;
}
public class Success implements Outcome {
public boolean success() {
return true;
}
public String error() {
return "";
}
}
public class Failure implements Outcome {
String error; //or call it reason
public Failure(String error) {
this.error = error;
}
public boolean success() {
return false;
}
public String error() {
return error;
}
}
And in controller, checking outcome.success(), and proceeding according to the result.
Is there a more elegant/oop way of doing this? Maybe like passing in success and failure callbacks to service methods as parameters, or some better way.
let me give you a concrete code example to clarify:
A new user, chooses a username for himself by writing it in a text field, then presses OK button.
- SUCCESS: user is registered
- FAIL: if there's already a user with the same name, user is prompted to choose a different name
- FAIL: some other problem, let's say system is not accepting new registrations at the moment
- FAIL: username is a word marked as offensive
as you see there are different outcomes for a method call, and for each outcome a different action must be taken.
public class UserService {
public Outcome register(String username)...
}
public class RegistrationController {
...
//somewhere inside controller, there is a handler for OK button's click event
onclick...
Outcome outcome = userService.register(username);
if(outcome.success())
...
else {
if(outcome.error() == "OFFENSIVE_USERNAME"
//... other outcomes
}
...
}
Best Answer
I had this question for REST a while ago, and I used this answer. It provides good information about the outcome of the service. It is also written in Java ;-)
With this design you can write your service methods like this:
public AbstractResponse getAllUsers() {}
. Also, because of the polymorphism, you can add other responses as well. For example, I needed an extra response for when a warning happens, and so I created aWarningResponse
class.Note that you can leave out the Status enum if you're using this in Java only. I converted my objects to JSON so I needed some kind of variable to show the status.