Passing a method as argument and call it later in Java

Java 8 introduced lambdas and since then Java got introduced to Functions. One of my favourite features that was always present in interpreted languages, such as JavaScript and Ruby, which is to pass a method as argument and call it inside another method.

It is already a consensus that the functional programming paradigm brings benefits, such as improvement in code readability, reusability, true parallelism, etc.

One interesting refactoring experience I had a week ago was to reduce the number of ifs in a class.

“monitor showing computer application” by Maximilian Weisbecker on Unsplash

This class was acting like a “gateway” or a “router”: depending on the string passed into the payload, this class would know where to redirect and how to forward this request to another service (if it should be a POST, GET, PUT, request etc.).


Static methods can be “converted” to functions

Since Java 8 we have the double column operator which return us a method reference. This allow us to create a function “on the fly”. It is common to see method references being used inside lambdas. 
So what we are doing here is exactly the same, but “delaying” a function call to be fired depending on a condition. Pay attention to the construction below, the operator in this case returns a Function, so we can start doing some magic! :)

Function<APayload, ClientResponse> post = RESTClientUtil::doPost;

With this we can code our “router” with a simple Map:

public class Router {
   public static final Map<String, Function<APayload, ClientResponse>> services = new HashMap<>();
   static {
Function<APayload, ClientResponse> post = RESTClientUtil::doPost;
Function<APayload, ClientResponse> get = RESTClientUtil::doGet;
Function<APayload, ClientResponse> put = RESTClientUtil::doPut;
      services.put("/oneEndpointPost", post);
services.put("/oneEndpointGet", get);
services.put("/oneEndpointPut", put);
}
   ...
}

Finally we can then fire which request do based in the string (serviceUrl) passed as argument going directly to the Map’s key!

Function<APayload, ClientResponse> httpService = Router.services.get(serviceUrl);
if (httpService != null) {
httpService.apply(payload);
}

So here is a nice example where Functions can help improve your code A LOT! We don’t need to check which HTTP Method we should fire in each case depending in the serviceUrl string passed as argument. We simply return it directly from our small “directory”. In case a new service enters on the router, we just need to add it into the Router class and the rest of the code will stay intact.

Hope this post can help you in refactoring some big chain of ifs in your code!

Any doubts or improvements into this post or in the code itself feel free to get in touch!!!

Like what you read? Give Jefferson Bicca a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.