1
\$\begingroup\$

I'm developing a Java 8 + JSF application, where all the view classes extend from an abstract class called Navegable.

All the methods called from the view and intended to modify the DB in any way, have to add an information message if everything goes OK or an error message otherwise. This involves wrapping many of my methods in a try-catch clause. In order to avoid that, I've tought I could use functional programming and prepare some generic function in the parent class instead. This way:

public abstract class Navegable implements Serializable {
 protected FacesUtils facesUtils;
 protected void execute(Function<Void, Void> function) {
 try {
 function.apply(null);
 facesUtils.addInfoMessage("PROPERLY_SAVED");
 } catch (Exception ex) {
 facesUtils.addErrorMessage("ERROR");
 throw ex;
 }
 }
 public Navegable(FacesUtils facesUtils) {
 super();
 this.facesUtils = facesUtils;
 }
}

Then I'd have to call it from each of my methods modifying the DB in children classes:

public class NavegableEquipment extends Navegable {
 public void assignWorker() {
 execute(new Function<Void, Void>() {
 @Override
 public Void apply(Void t) {
 assignWorker(selectedEquipment);
 reloadEquipmentById(selectedEquipment.get_Id());
 return null;
 }
 });
 }
 //More methods
}

However, the caller method still looks like a bit verbose in its implementation. Do I have any other choice or am I limited by the language itself?

asked Jul 13, 2016 at 7:27
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

First of all, Function<Void, Void> is not an appropriate choice of functional interface for this purpose.

Function<T,R> implementation should receive an instance of T and return an instance of R (although T and R still can be of same type).

If there is no incoming type, this looks like a Supplier.

If there is no returned type, it resembles a Consumer.

If there are no types to specify, Runnable can be used, but it'd better be kept for its initial concurrent usage.

So a dedicated functional interface can be created to solve the problem:

@FunctionalInterface
interface ExecutedWithFacesLogger {
 void executeWithFacesLogger();
}

Now, the execute method changes to the following:

protected void execute(ExecutedWithFacesLogger function) {
 try {
 function.executeWithFacesLogger();
 facesUtils.addInfoMessage("PROPERLY_SAVED");
 } catch (Exception ex) {
 facesUtils.addErrorMessage("ERROR");
 throw ex;
 }
}

And the caller is reduced to:

public void assignWorker() {
 execute(() -> {
 assignWorker(selectedEquipment);
 reloadEquipmentById(selectedEquipment.get_Id());
 });
}
answered Jul 13, 2016 at 9:00
\$\endgroup\$
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.