Java – Pattern for a method call outcome

javalayersmvc

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 a WarningResponse 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.

Related Topic