Good use of Closures

Court-Closure Not long ago, in a blog post, I explained what Closure were in Groovy. This blog post will explain one good example of using them. I recently found myself having to write the same exception handling logic for a bunch of back-end Controller APIs which were serving AJAX requests. It was like this:
 
 
 
 

class ApiRugbyPlayerController {
    JSON getPlayerStats() {
        try {
            ...
            // invoke business service method to get player stats
        } catch (ServiceException serviceException) {
            // don't care too much about this.
            // log and move on
            ...          
        } catch (SessionException sessionException) {
            // clear out session cookies
            ...
            // send 403 to client
            ...
        } catch (Exception ex) {
            throw new ApiException(ex)
        }
    }
 
    JSON updatePlayerStats() {
        try {
            ...
            // invoke business service method to update player stats
        } catch (ServiceException serviceException) {
            // don't care too much about this.
            // log and move on
            ...          
        } catch (SessionException sessionException) {
            // clear out session cookies
            ...
            // send 403 to client
            ...
        } catch (Exception ex) {
            throw new ApiException(ex)
        }
    }
 
    JSON queryPlayerStats(){
        try {
            ...
            // invoke business service method to query player stats
        } catch (ServiceException serviceException) {
            // don't care too much about this.
            // log and move on
            ...          
        } catch (SessionException sessionException) {
            // clear out session cookies
            ...
            // send 403 to client
            ...
        } catch (Exception ex) {
            throw new ApiException(ex)
        }
    }
}

As can be seen, there is some code duplication going on here. In the spirit of DRY (don’t repeat yourself), it is better to only define this exception handling logic once and then re-use it. So I defined the following utility method, which implements the exception handling pattern and takes a closure which is executes the exception handling for.

private JSON withExceptionHandling(Closure c) {
        try {
            ...
            c.call();
        } catch (ServiceException serviceException) {
            // don't care too much about this. 
            // log and move on
            ...           
        } catch (SessionException sessionException) {
            // clear out session cookies
            ...
            // send 403 to client 
            ...
        } catch (Exception ex) {
            throw new ApiException(ex)
        }
    }

We can make a code block a closure in Groovy by surrounding it with {}. This means I can make the logic inside my Controller methods into Closures and pass them to my utility method. And when I pass it to my utility method I don’t even need to pass it inside a () as Groovy doesn’t make you. So that means, I can take out all the common exception handling, remove the code bloat and my Controller API’s are much cleaner.

class ApiRugbyPlayerController {
    JSON getPlayerStats() {
        withExceptionHandling {
            ...
            // invoke business service method to get player stats
        } 
    }

    JSON updatePlayerStats() {
        withExceptionHandling {
            ...
            // invoke business service method to update player stats
        } 
    }

    JSON queryPlayerStats(){
        withExceptionHandling {
            ...
            // invoke business service method to query player stats
        } 
    }

    private JSON withExceptionHandling(Closure c) {
        try {
            ...
            c.call();
        } catch (ServiceException serviceException) {
            // don't care too much about this. 
            // log and move on
            ...           
        } catch (SessionException sessionException) {
            // clear out session cookies
            ...
            // send 403 to client 
            ...
        } catch (Exception ex) {
            throw new ApiException(ex)
        }
    }
}

So there we go. We have adhered to DRY principles, avoided code bloat and have a dedicated place for our exception handling confident that it being implemented consistently. This example of Groovy closure is a little but like a second order invocation in JavaScript. If we wanted to do something like in Java, it would just involve a lot more code. We could use something like the command pattern and put the execution of them into the exception handling logic. You would have more decoupling, but you have a lot more code. Or you could make all your AJAX APIs enter a common method (like a Front Controller) and but your common exception handling there. Again, possible but just more code. Until the next time, take care of yourselves.
 

Reference: Good use of Closures from our JCG partner Alex Staveley at the Dublin’s Tech Blog blog.
Related Whitepaper:

Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions

Get ready to program in a whole new way!

Functional Programming in Java will help you quickly get on top of the new, essential Java 8 language features and the functional style that will change and improve your code. This short, targeted book will help you make the paradigm shift from the old imperative way to a less error-prone, more elegant, and concise coding style that’s also a breeze to parallelize. You'll explore the syntax and semantics of lambda expressions, method and constructor references, and functional interfaces. You'll design and write applications better using the new standards in Java 8 and the JDK.

Get it Now!  

Leave a Reply


nine + 3 =



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

20,709 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books