HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Passing input parameters correctly to a method

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
methodpassinginputparameterscorrectly

Problem

Below is my Interface:

public interface IDBClient {
    public String read(ClientInput input);
}


This is my implementation of the interface:

public class DatabaseClient implements IDBClient {

    @Override
    public String read(ClientInput input) {

    }
}


Now I have a factory which gets the instance of DatabaseClient like this:

IDBClient client = DatabaseClientFactory.getInstance();
....


Now I need to make a call to read method of my DatabaseClient which accepts the ClientInput parameter and below is the class for the same. This class was not written by me so that is the reason I am having a question on this and I am pretty much sure this is the wrong way of doing it.

public final class ClientInput {

    private Long userid;
    private Long clientid;
    private Long timeout_ms = 20L;
    private boolean debug;
    private Map parameterMap;

    public ClientInput(Long userid, Long clientid, Map parameterMap, Long timeout_ms, boolean debug) {
        this.userid = userid;
        this.clientid = clientid;
        this.parameterMap = parameterMap;
        this.timeout_ms = timeout_ms;
        this.debug = debug;
    }
}


So when customer make a call to read method of DatabaseClient, they will create the ClientInput parameter like this and then use the factory to get the Instance of DatabaseClient and then call the read method accordingly.

Map paramMap = new HashMap();
paramMap.put("attribute", "segmentation");

ClientInput input = new ClientInput(109739281L, 20L, paramMap, 1000L, true);

IDBClient client = DatabaseClientFactory.getInstance();
client.read(input);


Is this the right way of creating the ClientInput and then passing it to the read method? If not, then what's the best way of doing it? Where should I be doing validation check to see whether the customer has passed valid user IDs or valid client ID, etc.?

Solution

Like most times, it is best to validate your data before you use it. In your case, since the input data needs to be validated by the Database infrastructure, I recommend adding it to the IDBClient interface.

I also assume that the paramMap is the query you want to run, and not part of the user/login information.

I suspect the logical thing to do is to extend your interface to look like:

public interface IDBClient {

    public interface SessionHandle extends AutoCloseable, Closeable {
        public boolean isAlive();
    }

    public SessionHandle createSession(Long userid, Long clientid,
              Long timeout_ms, boolean debug) throws InvalidLoginException;

    public String read(SessionHandle session, Map parameterMap)
              throws ReadNotPossibleException, SessionExpiredException;
}


Now you are forced to create a SessionHandle instance that is pre-verified, and immutable. The content of that SessionHandle is whatever it needs to be for your actual IDBClient implementaton. The IDBClient implementation will know which handles are valid, and can do other things with the handle as needed.

Because times are good, and Java7 is better, you should also ensure that your SessionHandle is AutoCloseable so you can use try-with-resources.

Your Exceptions (which you should create custom versions of) for your interface should all extend a single Exception class, for example:

public DBClientException extends Exception { ..... }
public ReadNotPossibleException extends DBClientException {....}
public SessionExpiredException extends DBClientException {...}


by doing this, you can allow the user to catch just the database exception, or more-specific database exception sub-types if needed....

The 'user experience' will look like:

IDBClient client = DatabaseClientFactory.getInstance();
try (IDBClient.SessionHandle session =
          client.createSession( 109739281L, 20L, 1000L, true) ) {

    String result = client.read(session, paramMap);

} catch (DBClientException e) {
    .....
}

Code Snippets

public interface IDBClient {

    public interface SessionHandle extends AutoCloseable, Closeable {
        public boolean isAlive();
    }

    public SessionHandle createSession(Long userid, Long clientid,
              Long timeout_ms, boolean debug) throws InvalidLoginException;

    public String read(SessionHandle session, Map<String, String> parameterMap)
              throws ReadNotPossibleException, SessionExpiredException;
}
public DBClientException extends Exception { ..... }
public ReadNotPossibleException extends DBClientException {....}
public SessionExpiredException extends DBClientException {...}
IDBClient client = DatabaseClientFactory.getInstance();
try (IDBClient.SessionHandle session =
          client.createSession( 109739281L, 20L, 1000L, true) ) {

    String result = client.read(session, paramMap);

} catch (DBClientException e) {
    .....
}

Context

StackExchange Code Review Q#38962, answer score: 3

Revisions (0)

No revisions yet.