Java – How do I make a block of code that contains a return statement into a function?

How do I make a block of code that contains a return statement into a function?… here is a solution to the problem.

How do I make a block of code that contains a return statement into a function?

If I have a similar block of code that is used in many places but has different functions but contains return statements, how can I reorganize it to make this block a function? For example, let’s say I have an object Mailman, which contains a valid code (successful/failed/failed reason) and possibly a package for the callee.

In one case, Postman might just pick up the element he’s holding and give it to the callee:

Mailman mailman = requestMailForPerson(person);

switch(mailman.getStatus()){
   case SUCCESS:
      Mail mail = (Mail)mailman.getHeldItem();
      return Response.ok().entity(mail).build();
   case PERSON_DOESNT_EXIST:
      return Response.status(Response.status.BAD_REQUEST).build();
   case MAIL_SERVICE_FAILED_SOMEWHERE:
      return Response.status(Response.status.INTERNAL_SERVER_ERROR).build();
}

But at another he may be resending a letter

Mailman mailman = rerouteLetterForPerson(letter, person);

switch(mailman.getStatus()){
   case SUCCESS:
      Letter letter = (Letter)mailman.getHeldItem();
      if(distance(letter.address, currentLocation) > 50){
          sendToNextoffice(letter);
          return Response.ok.entity("in transit").build();
      }else{
          return Response.ok().entity(letter).build();
      }

case PERSON_DOESNT_EXIST:
      return Response.status(Response.status.BAD_REQUEST).build();
   case MAIL_SERVICE_FAILED_SOMEWHERE:
      return Response.status(Response.status.INTERNAL_SERVER_ERROR).build();
}

Only blocks of code that look very similar, I want to break this logic down somewhere, but dealing with different success/failure scenarios makes me sad.

Solution

You already have the answer “half” in your code:

Mailman mailman = requestMailForPerson(person);

Contrast

Mailman mailman = rerouteLetterForPerson(letter, person);

The key point here is that those Mailman class objects that should not be “identical”. Mailman can be an interface, and your method will return a different implementation of it!

Then you just call a method

mailman.doYourJob();

You get the right results; Depends on the underlying implementation code!

In a sense, you are absolutely right, because such internal state switching code has a very bad smell. It violates the Tell Don’t Ask principle. This is the part you really want to avoid: you don’t want to want to externalize that state and let other “external” code make decisions based on that state!

Related Problems and Solutions