diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/eam/Retry.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/eam/Retry.java new file mode 100644 index 0000000..4927fa5 --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/behavioral/eam/Retry.java @@ -0,0 +1,37 @@ +package pl.mperor.lab.java.design.pattern.behavioral.eam; + +import java.util.function.Supplier; + +public class Retry { + + private final int retries; + + private Retry(int retries) { + this.retries = retries; + } + + public T retry(Supplier action) { + Exception lastException = null; + + for (int i = 0; i < retries; i++) { + try { + return action.get(); + } catch (Exception e) { + lastException = e; + } + } + + throw new NoRetriesRemainException("Failed to execute action after %s attempts".formatted(retries), lastException); + } + + public static Retry of(int retries) { + return new Retry(retries); + } + + public static class NoRetriesRemainException extends RuntimeException { + public NoRetriesRemainException(String message, Throwable cause) { + super(message, cause); + } + } + +} \ No newline at end of file diff --git a/DesignPatterns/src/test/java/pl/mperor/lab/java/design/pattern/behavioral/eam/ExecuteAroundMethodTest.java b/DesignPatterns/src/test/java/pl/mperor/lab/java/design/pattern/behavioral/eam/ExecuteAroundMethodTest.java new file mode 100644 index 0000000..231531b --- /dev/null +++ b/DesignPatterns/src/test/java/pl/mperor/lab/java/design/pattern/behavioral/eam/ExecuteAroundMethodTest.java @@ -0,0 +1,33 @@ +package pl.mperor.lab.java.design.pattern.behavioral.eam; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import pl.mperor.lab.common.TestUtils; + +import java.util.List; +import java.util.stream.IntStream; + +public class ExecuteAroundMethodTest { + + @Test + public void shouldAllowToUseExecuteAroundMethod() { + var out = TestUtils.setTempSystemOut(); + executeAround(() -> System.out.println("action")); + Assertions.assertLinesMatch(List.of("setup", "action", "tear down"), out.lines()); + TestUtils.resetSystemOut(); + } + + private static void executeAround(Runnable action) { + System.out.println("setup"); + action.run(); + System.out.println("tear down"); + } + + @Test + public void testRetry() { + var exception = Assertions.assertThrows(Retry.NoRetriesRemainException.class, () -> Retry.of(3).retry(() -> 1 / 0)); + Assertions.assertInstanceOf(ArithmeticException.class, exception.getCause()); + Assertions.assertEquals(10, Retry.of(1).retry(() -> IntStream.rangeClosed(1, 4).sum())); + } + +}