1

So I wanted to reuse some functionalities like the try catch and some other common functionalities used by my application. I was wondering if this approach is ok. Or if there is any other approach that would be great. I want to learn the different ways on how I can implement this.

This is a callback function that services will use.

 public interface ClientOperation <T>{
      T doAction(SomeObject someObject);
    }

And this is the interface which will execute the callback function of ClientOperation

 public interface Executor {

    <T> T doTask(ClientOperation<T> operation);
    }

The implementation class of Executor

    public class ExecutorImpl implements Executor {



    public <T> T doTask(ClientOperation<T> operation) {
        T response = null;
        /*
            DO SOMETHING FIRST - USED BY ALL CLASSES
        */

        try {
            response = operation.doAction(someObject);
        } catch (SomeException e) {
            /*
                DO SOME SERIOUS STUFF
            */

        } catch (Exception e) {
            LOGGER.error(e.getMessage());
            throw new SystemException(e.getMessage(), e);
        }

        return response;
    }
}

A service that does something and implements the callback function

public void addSomething(final Secret secret)
            throws UnauthorizedActionException, InvalidSecretKeyException {

            executorService.doTask(new ClientOperation<Response>() {
                public Response doAction(SomeObject someObject) {

                //DO STUFF ON THIS
                    return template.write(secret.getPath(),
                            secret.getSecretValue());

                }
            });


}
Eldon Hipolito
  • 704
  • 1
  • 8
  • 24

1 Answers1

1

I want to learn the different ways on how I can implement this.

Your approach seems perfectly fine. I would take it one step further and make the input (i.e SomeObject) generic as well so that ClientOperation can work with different input types.

public interface ClientOperation <T,S>{
      T doAction(S someObject);
}

An alternate approach would be to use the Template Method pattern where ClientOperation is converted to an abstract class with an abstract doAction method and a concrete final doTask method that calls doAction in a try-catch block. Subclasses provide the implementation for the doAction method. A drawback of this approach would be that you can't extend from any other class.

Community
  • 1
  • 1
Chetan Kinger
  • 15,069
  • 6
  • 45
  • 82
  • 1
    Great! Thanks for the feedback. I also think that template method also limit the concrete subclasses to 1 implementation method. – Eldon Hipolito Feb 17 '17 at 02:29