On others code

July 22, 2018

Johannes Brodwall posted Dirty Code Monday on his, eh, blog, to show some of the dirty code he let through, which he otherwise would not. In this he also highlighted what about the code he thought was dirty.

This lead me to make an unfortunate tweet

What scares me most about the code you’re showing is how tightly coupled the logic is to its environment. A bunch of the values you use in your functions could easily be passed as parameters.

— Erik Assum (@slipset) July 2, 2018

Unfortunate, because I was critizising something that was already pointed out as bad.

Anyways, I thought I’d try to enumerate what I found smelly about the code. This is kind of hard, since I no longer write Java, and I most certainly don’t know the surroundings of the code in question.

But let’s jump into it.

For the first example, I think I would have pulled the if-test out of this function, and made it accept only a HttpsURLConnection:

public static void setupClientCertificate(HttpsURLConnection httpsURLConnection) throws IOException {
    HttpsURLConnection httpsURLConnection = (HttpsURLConnection) httpURLConnection;
    try {
        // TODO: Find out if SSLContext.getSocketFactory is expensive an if so, cache
        httpsURLConnection.setSSLSocketFactory(createSocketFactory(keyStorePath(), keystorePassword(), trustStorePath()));
    } catch (KeyStoreException | CertificateException | NoSuchAlgorithmException | UnrecoverableKeyException | KeyManagementException e) {
        throw new RuntimeException(e);
    }
}

Now this code is somewhat logic free, and it’s up to the caller to check if we’re using client certs and make the cast. Still not happy with it though, but I can’t really put my finger on what bugs me.

For the second example, my biggest problem is that, at least the last time I programmed Java, you needed a mock for HttpServletRequest to set values on it. And I really dislike mocks. Therefore, I’d like to rewrite it as

private boolean isValidRequest(String method, String pathInfo) {
    List<String> validPaths = method.equals("GET") ? Configuration.validGetPaths() : Configuration.validPostPaths();
    return pathInfo != null && validPaths.stream().anyMatch(pathInfo::startsWith);
}

Now this method has two String arguments, not to happy about that either.

Guess the method should have been an Enum.

Also not overly enthused about the whole Configuration bit. I guess I would have rewritten to Configuration.validPaths(method);, which would leave us with:

private boolean isValidRequest(HttpMethod method, String pathInfo) {
    List<String> validPaths = Configuration.validPaths(method);
    return pathInfo != null && validPaths.stream().anyMatch(pathInfo::startsWith);
}

Which, in which you could let the caller do the validPaths thingy, so it ends up around

private boolean isValidRequest(List<String> validPaths, String pathInfo) {
    return pathInfo != null && validPaths.stream().anyMatch(pathInfo::startsWith);
}

And you have a function which is quite testable, and does its one thing.

Anyways, thanks for posting this Johannes, it made me think.