Execute around pattern in Groovy

November 7, 2012 at 11:41

The execute around pattern seems to be a common practice in fuctional related languages (although probably Rafael Luque would claim that, as almost everything else 😀 , made it first appearance in Smalltalk, and Marcin Gryszko would say that is just the old plain template method 😀 ), but it’s probably kind of new to Groovy programmers who come from Java, where it can be implemented, but doesn’t feel as natural as in Groovy.

The idea is pretty simple: when you have different peaces of code that are enclosed by the same “header” and “footer” code, you should extract this header and footer to a new method that receives the changing code as a parameter. Simple but powerful. The typical example is the usage of a resource that must be opened before using it and closed after:

def someWritingMethod(filePath, stuffToWrite) {
   file.open(filePath)
   file.write(stuffToWrite)
   file.close()
}

def someReadingMethod(filePath, charsToRead) {
   file.open(filePath)
   def readStuff = file.read(charsToRead)
   file.close()
   readStuff
}

With execute around, this could be changed to the following:

def someWritingMethod(filePath, stuffToWrite) {
   withFile(filePath) { file ->
      file.write(stuffToWrite)
   }
}

def someReadingMethod(filePath, charsToRead) {
   withFile(filePath) { file ->
      file.read(charsToRead)
   }
}

private withFile(filePath, Closure fileUser) {
   def file = file.open(filePath)
   def result = fileUser(file)
   file.close()
   result
}

As you can see, the second code have multiple benefits: first and most important, we avoid duplicated code, the worse thing that a programmer could do. Secondly, we simplify our business logic methods by not defining variables that will be used later (for example, in someReadingMethod, we define readStuff for later returning this, forcing the person that is mantaining our code to read more of it just to be sure that the readStuff variable is not modified later).

This is the most simple case, but there are tons of usages that you wouldn’t probably think of. Here is a Grails inspired example that deals with one of our most beloved friends from the Java world, the try-catch:

class UserController {
     
    def userService

    def updateUser(userId) {
        treatExpectedExceptions('index', userId) {
            userService.updateUser(userId, params)
        }
    }

    def updateUserGroup(userId, groupId) {
        treatExpectedExceptions('showGroup', userId) {
            userService.changeUserGroup(userId, groupId)
        }
    }

    private treatExpectedExceptions(actionToRedirect, userId, Closure exceptionThrower) {
         try {
            exceptionThrower()
            flash.message = "action.$actionToRedirect.success"
            redirect action: action, id: userId
         } 
         catch (MultipleValidationException validationException) {
            flash.error = "action.$actionToRedirect.validation.failure"
            redirect action: action, id: userId, params: [ invalidFields : formatInvalidFields(validationException) ]
         }
         catch (UserNotFoundException userNotFoundException) {
            response.sendError HttpServletResponse.SC_NOT_FOUND
         }
    }
}

As you can see, the user controller always follows the same structure: it tries to perform some business logic with a supplied user id. When the logic fails because of the user id not corresponding to an existing user, a 404 response is sent. If the logic fails because the changes made to the user are not valid, a error message is set and the invalid fields are included in the redirect parameters in order to be formatted in the view. And if the logic doesn’t fail, a success message is set and a plain redirect is done.

Here you can sense another benefit of using the pattern: when another programmer have to add a new method to the controller, he will see the existing code and probably will try to adapt the new method to use the treatExpectedExceptions, leading the UserController to be a uniform and easy to understand class. And by not having to rewrite all the exceptions logic, the UserController has became an easy to extend class too 🙂 .

And this is just an example that I made up while writting the post, but probably could be used in multiple controllers in the projects I’m currently working 🙂 . So, as you can see, is a really simple idea that can be really powerful.