Skip to content

Commit 59d3e52

Browse files
committed
docs: improve execute around
1 parent 9615fd9 commit 59d3e52

File tree

3 files changed

+57
-32
lines changed

3 files changed

+57
-32
lines changed

execute-around/README.md

Lines changed: 53 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,47 @@
11
---
22
title: Execute Around
3-
category: Idiom
3+
category: Behavioral
44
language: en
55
tag:
6-
- Extensibility
6+
- Closure
7+
- Code simplification
8+
- Encapsulation
9+
- Functional decomposition
10+
- Resource management
711
---
812

13+
## Also known as
14+
15+
* Around Method Pattern
16+
* Resource Block Management
17+
918
## Intent
1019

11-
Execute Around idiom frees the user from certain actions that should always be executed before and
12-
after the business method. A good example of this is resource allocation and deallocation leaving
13-
the user to specify only what to do with the resource.
20+
Execute Around idiom frees the user from certain actions that should always be executed before and after the business method. A good example of this is resource allocation and deallocation leaving the user to specify only what to do with the resource.
1421

1522
## Explanation
1623

1724
Real-world example
1825

19-
> A class needs to be provided for writing text strings to files. To make it easy for
20-
> the user, the service class opens and closes the file automatically. The user only has to
21-
> specify what is written into which file.
26+
> A class needs to be provided for writing text strings to files. To make it easy for the user, the service class opens and closes the file automatically. The user only has to specify what is written into which file.
2227
2328
In plain words
2429

25-
> Execute Around idiom handles boilerplate code before and after business method.
30+
> Execute Around idiom handles boilerplate code before and after business method.
2631
2732
[Stack Overflow](https://stackoverflow.com/questions/341971/what-is-the-execute-around-idiom) says
2833

29-
> Basically it's the pattern where you write a method to do things which are always required, e.g.
30-
> resource allocation and clean-up, and make the caller pass in "what we want to do with the
31-
> resource".
34+
> 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".
3235
3336
**Programmatic Example**
3437

35-
`SimpleFileWriter` class implements the Execute Around idiom. It takes `FileWriterAction` as a
36-
constructor argument allowing the user to specify what gets written into the file.
38+
`SimpleFileWriter` class implements the Execute Around idiom. It takes `FileWriterAction` as a constructor argument allowing the user to specify what gets written into the file.
3739

3840
```java
41+
3942
@FunctionalInterface
4043
public interface FileWriterAction {
41-
void writeFile(FileWriter writer) throws IOException;
44+
void writeFile(FileWriter writer) throws IOException;
4245
}
4346

4447
@Slf4j
@@ -54,18 +57,18 @@ public class SimpleFileWriter {
5457
}
5558
```
5659

57-
The following code demonstrates how `SimpleFileWriter` is used. `Scanner` is used to print the file
58-
contents after the writing finishes.
60+
The following code demonstrates how `SimpleFileWriter` is used. `Scanner` is used to print the file contents after the writing finishes.
5961

6062
```java
61-
FileWriterAction writeHello = writer -> {
62-
writer.write("Gandalf was here");
63-
};
63+
// create the file writer and execute the custom action
64+
FileWriterAction writeHello = writer -> writer.write("Gandalf was here");
6465
new SimpleFileWriter("testfile.txt", writeHello);
6566

66-
var scanner = new Scanner(new File("testfile.txt"));
67-
while (scanner.hasNextLine()) {
68-
LOGGER.info(scanner.nextLine());
67+
// print the file contents
68+
try (var scanner = new Scanner(new File("testfile.txt"))) {
69+
while (scanner.hasNextLine()) {
70+
LOGGER.info(scanner.nextLine());
71+
}
6972
}
7073
```
7174

@@ -84,10 +87,35 @@ Here's the console output.
8487

8588
## Applicability
8689

87-
Use the Execute Around idiom when
90+
* Useful in scenarios requiring repetitive setup and cleanup activities, particularly in resource management (e.g., files, network connections, database sessions).
91+
* Ideal for ensuring proper resource handling and cleanup in the face of exceptions, ensuring resources do not leak.
92+
* Suitable in any Java application where the same preparation and finalization steps are executed around varying core functionalities.
93+
94+
## Known Uses
95+
96+
* Java's try-with-resources statement, which ensures that resources are closed after execution regardless of whether an exception was thrown.
97+
* Frameworks like Spring for managing database transactions, where predefined cleanup or rollback operations are performed depending on the execution outcome.
98+
99+
## Consequences
100+
101+
Benefits:
102+
103+
* Reduces boilerplate code by abstracting routine setup and cleanup tasks.
104+
* Increases code clarity and maintainability by separating business logic from resource management.
105+
* Ensures robustness by automatically handling resource cleanup, even in error situations.
106+
107+
Trade-offs:
108+
109+
* Introduces additional abstraction layers, which might increase complexity and obscure control flow for some developers.
110+
* May require more sophisticated understanding of closures and functional interfaces in Java.
111+
112+
## Related Patterns
88113

89-
* An API requires methods to be called in pairs such as open/close or allocate/deallocate.
114+
* [Template Method](https://java-design-patterns.com/patterns/template-method/): Similar in concept but differs in that it uses inheritance and abstract classes, while Execute Around typically uses interfaces and lambdas.
115+
* [Decorator](https://java-design-patterns.com/patterns/decorator/): Shares the concept of adding functionality around a core component; can be extended to wrap additional behaviors dynamically.
90116

91117
## Credits
92118

119+
* [Effective Java](https://amzn.to/4aDdWbs)
120+
* [Java Design Patterns: A Hands-On Experience with Real-World Examples](https://amzn.to/3vUGApm)
93121
* [Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions](https://www.amazon.com/gp/product/1937785467/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1937785467&linkCode=as2&tag=javadesignpat-20&linkId=7e4e2fb7a141631491534255252fd08b)

execute-around/src/main/java/com/iluwatar/execute/around/App.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
import lombok.extern.slf4j.Slf4j;
3131

3232
/**
33-
* The Execute Around idiom specifies executable code before and after a method. Typically
33+
* The Execute Around idiom specifies executable code before and after a method. Typically,
3434
* the idiom is used when the API has methods to be executed in pairs, such as resource
3535
* allocation/deallocation or lock acquisition/release.
3636
*
@@ -47,9 +47,7 @@ public class App {
4747
public static void main(String[] args) throws IOException {
4848

4949
// create the file writer and execute the custom action
50-
FileWriterAction writeHello = writer -> {
51-
writer.write("Gandalf was here");
52-
};
50+
FileWriterAction writeHello = writer -> writer.write("Gandalf was here");
5351
new SimpleFileWriter("testfile.txt", writeHello);
5452

5553
// print the file contents

execute-around/src/test/java/com/iluwatar/execute/around/AppTest.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,13 @@
2424
*/
2525
package com.iluwatar.execute.around;
2626

27+
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
28+
2729
import java.io.File;
28-
import java.io.IOException;
2930
import org.junit.jupiter.api.AfterEach;
3031
import org.junit.jupiter.api.BeforeEach;
3132
import org.junit.jupiter.api.Test;
3233

33-
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
34-
3534
/**
3635
* Tests execute-around example.
3736
*/

0 commit comments

Comments
 (0)