What are the alternatives ways of desiging following interactive API?

Viewed 49

A simple version of the interface is:

public interface IAPI {
   void initialize(int processId) throws APIException;
   APIResult process(IData data) throws APIException;
   void finalize();
}

Finalize method creates a summary report on data that is processed (very important information for me) but is not crucial for a client.

The API is consumed like:

IAPI api = new API();
api.initialize(18);
loop {
       IData data = …..getData!
       APIResult res = api.process(data);

       // do something with result.
}

// Finalize - We want to enforce the finalize call
api.finalize();

I need a solution to ensure that the finalize method is called when they are done processing their data. The solution has to be flexible enough to let user define how they want to handle exceptions, process as many data as they want. Thanks in advance for any alternatives.

1 Answers

I'd do something like this:

import java.util.function.Function;

public class Test {
    static class APIException extends Exception {}
    static class APIResult {}
    static class IData {}
    
    // This is the public API
    interface  IAPI {
        <T> T withIDataProcessor(Function<IDataProcessor,T> process) throws APIException;

        interface IDataProcessor {
            APIResult process(IData idata);
        }
    }
    
    // only the DefaultIAPI class knows about this
    interface PrivateIAPI {
        void initialize(int processId) throws APIException;
        APIResult process(IData data) throws APIException;
        void finalize();
    }

    static class DefaultIAPI implements IAPI {
        private PrivateIAPI privateIAPI;

        @Override
        public <T> T withIDataProcessor(Function<IDataProcessor, T> process) throws APIException {
            try {
                privateIAPI.initialize(5);
                return process.apply(idata -> {
                    try {
                        return privateIAPI.process(idata);
                    } catch (APIException e) {
                        // handle this in some way
                        throw new RuntimeException(e);
                    }
                });
            } finally {
                privateIAPI.finalize();
            }
        }
    }

    public static void main(String[] args) {
        IAPI iapi = new DefaultIAPI();
        int result = iapi.withIDataProcessor(idataProcessor -> {
            while (idataProcessor.process(...getData())) {
                ...
            }
            return n;
        });
    }
}

(note the main method doesn't compile, and the exception handling needs more thought)

Related