DEV Community

Kai Sawamoto
Kai Sawamoto

Posted on

Execute Around Method (EAM) Pattern | Design Patterns

What can you learn?

  • What problem Execute Around Method design pattern solves
  • How EAM works

Prerequisite

  • Basic understanding of how lambda expression works
  • Just a little bit of software development experience

Why EAM pattern?

It is crucial to close file writers

Have you wrote a code like this and wondered why the file is not being written?

void main() {
    final FileWriterExample writer = new FileWriterExample("peekaboo.txt");
    writer.writeStuff("peek-a-boo");
}
Enter fullscreen mode Exit fullscreen mode

That is because, file writers retain the written content in a buffer, not persisting it right away. Therefore, it is required to close the writer before it flushes the buffer so that we can see the file update.

In addition to that, Java's garbage collector do not take care of releasing external resources such as database and files, which leads to waiting our precious memory.

In order to ensure such resources are released, Execute Around Method (EAM) pattern comes in handy.

(Imperfect) Improvement over the last code

void main(){
    final FileWriterExample writer = new FileWriterExample("peekaboo.txt");
    try  {
        writer.writeStuff("peek-a-boo");
    } finally {
        writer.close();
    }
}
Enter fullscreen mode Exit fullscreen mode

This code now ensures to close the file, even when the writer raises an exception thanks to the finally block.

However, this code is verbose and we need to write the try-finally block every single time we use the writer.

EAM pattern to the rescue

Using EAM pattern the code above can be rewritten as follows:

void write(String fileName, Consumer<FileWriterExample> block)  {
    final FileWriterExample writer = new FileWriterExample(fileName);
    try {
        block.accept(writerEAM);
    } finally {
        writerEAM.close();
    }
}

void main() {
    write("peekaboo.txt", writer -> {
        writer.writeStuff("nice");
        writer.writeStuff("clean");
    });
}
Enter fullscreen mode Exit fullscreen mode

We defined write method, which takes in a filename and a block. block is a type of Consumer, which is a java functional interface. Consumer is basically a function that takes a FileWriterExample class as an input and returns nothing.

As block, we can pass in a function pointer, a method reference, or a lambda expression.
In the example above, it is passing in a lambda expression.
write function takes care of creating a writer and closing it after invoking the code inside block.

The beauty is that inside the body of block, we have a free access to a writer instance without any concerns about cleaning up the resource, no matter how many times we call write.

There you have it. You now know how EAM pattern works.

Another usage

In Java we can use synchronized to make a function thread-safe like so: public synchronized void method() {...}.
This is exactly a realization of EAM pattern.

In stead of creating and closing a file writer, methods marked as synchronized acquire and release a mutex lock at the beginning and the end of the methods' lifetime.

Just food for thoughts.

Top comments (0)