Tom Hawtin - tackline Tom Hawtin - tackline - 1 month ago 5
Java Question

What is the "Execute Around" idiom?

What is this "Execute Around" idiom (or similar) I've been hearing about?
Why might I use it, and why might I not want to use it?

Answer

Basically it's the pattern where you write a method to do things which are always required, e.g. resource allocation and clean-up, and make the caller pass in "what we want to do with the resource". For example:

public interface InputStreamAction
{
    void useStream(InputStream stream) throws IOException;
}

// Somewhere else    

public void executeWithFile(String filename, InputStreamAction action)
    throws IOException
{
    InputStream stream = new FileInputStream(filename);
    try {
        action.useStream(stream);
    } finally {
        stream.close();
    }
}

// Calling it
executeWithFile("filename.txt", new InputStreamAction()
{
    public void useStream(InputStream stream) throws IOException
    {
        // Code to use the stream goes here
    }
});

// Calling it with Java 8 Lambda Expression:
executeWithFile("filename.txt", s -> System.out.println(s.read()));

// Or with Java 8 Method reference:
executeWithFile("filename.txt", ClassName::methodName);

The calling code doesn't need to worry about the open/clean-up side - it will be taken care of by executeWithFile.

This was frankly painful in Java because closures were so wordy, starting with Java 8 lambda expressions can be implemented like in many other languages (e.g. C# lambda expressions, or Groovy), and this special case is handled since Java 7 with try-with-resources and AutoClosable streams.

Although "allocate and clean-up" is the typical example given, there are plenty of other possible examples - transaction handling, logging, executing some code with more privileges etc. It's basically a bit like the template method pattern but without inheritance.