From 34863f15674bf212e84baa815a58650a99e81159 Mon Sep 17 00:00:00 2001 From: Luis Date: Wed, 11 Jun 2025 18:24:03 -0300 Subject: [PATCH] Add Template Method design pattern example --- README.md | 1 + .../templatemethod/AbstractClass.java | 12 ++++++++++ .../templatemethod/ConcreteClassA.java | 14 +++++++++++ .../templatemethod/ConcreteClassB.java | 14 +++++++++++ .../TemplateMethodExampleRunner.java | 24 +++++++++++++++++++ .../TemplateMethodExampleRunnerTests.java | 10 ++++++++ .../templatemethod/TemplateMethodTests.java | 14 +++++++++++ 7 files changed, 89 insertions(+) create mode 100644 src/main/java/com/penapereira/example/constructs/templatemethod/AbstractClass.java create mode 100644 src/main/java/com/penapereira/example/constructs/templatemethod/ConcreteClassA.java create mode 100644 src/main/java/com/penapereira/example/constructs/templatemethod/ConcreteClassB.java create mode 100644 src/main/java/com/penapereira/example/constructs/templatemethod/TemplateMethodExampleRunner.java create mode 100644 src/test/java/com/penapereira/example/constructs/templatemethod/TemplateMethodExampleRunnerTests.java create mode 100644 src/test/java/com/penapereira/example/constructs/templatemethod/TemplateMethodTests.java diff --git a/README.md b/README.md index 7a5baaa..c23ae5d 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ cd java-patterns-and-constructs * [Factory Method](src/main/java/com/penapereira/example/constructs/factorymethod/) * [Observer](src/main/java/com/penapereira/example/constructs/observer/) * [Singleton](src/main/java/com/penapereira/example/constructs/singleton/) +* [Template Method](src/main/java/com/penapereira/example/constructs/templatemethod/) ### Constructs and Problems * [Producer/Consumer](src/main/java/com/penapereira/example/constructs/producerconsumer/), a multi-process synchronization problem. diff --git a/src/main/java/com/penapereira/example/constructs/templatemethod/AbstractClass.java b/src/main/java/com/penapereira/example/constructs/templatemethod/AbstractClass.java new file mode 100644 index 0000000..89e9712 --- /dev/null +++ b/src/main/java/com/penapereira/example/constructs/templatemethod/AbstractClass.java @@ -0,0 +1,12 @@ +package com.penapereira.example.constructs.templatemethod; + +public abstract class AbstractClass { + + protected abstract String stepOne(); + + protected abstract String stepTwo(); + + public final String templateMethod() { + return stepOne() + " then " + stepTwo(); + } +} diff --git a/src/main/java/com/penapereira/example/constructs/templatemethod/ConcreteClassA.java b/src/main/java/com/penapereira/example/constructs/templatemethod/ConcreteClassA.java new file mode 100644 index 0000000..30ed916 --- /dev/null +++ b/src/main/java/com/penapereira/example/constructs/templatemethod/ConcreteClassA.java @@ -0,0 +1,14 @@ +package com.penapereira.example.constructs.templatemethod; + +public class ConcreteClassA extends AbstractClass { + + @Override + protected String stepOne() { + return "A step one"; + } + + @Override + protected String stepTwo() { + return "A step two"; + } +} diff --git a/src/main/java/com/penapereira/example/constructs/templatemethod/ConcreteClassB.java b/src/main/java/com/penapereira/example/constructs/templatemethod/ConcreteClassB.java new file mode 100644 index 0000000..3242514 --- /dev/null +++ b/src/main/java/com/penapereira/example/constructs/templatemethod/ConcreteClassB.java @@ -0,0 +1,14 @@ +package com.penapereira.example.constructs.templatemethod; + +public class ConcreteClassB extends AbstractClass { + + @Override + protected String stepOne() { + return "B step one"; + } + + @Override + protected String stepTwo() { + return "B step two"; + } +} diff --git a/src/main/java/com/penapereira/example/constructs/templatemethod/TemplateMethodExampleRunner.java b/src/main/java/com/penapereira/example/constructs/templatemethod/TemplateMethodExampleRunner.java new file mode 100644 index 0000000..5bbcaed --- /dev/null +++ b/src/main/java/com/penapereira/example/constructs/templatemethod/TemplateMethodExampleRunner.java @@ -0,0 +1,24 @@ +package com.penapereira.example.constructs.templatemethod; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import com.penapereira.example.constructs.app.ExampleRunnerInterface; + +@Component +public class TemplateMethodExampleRunner implements ExampleRunnerInterface { + + private static final Logger log = LoggerFactory.getLogger(TemplateMethodExampleRunner.class); + + @Override + public void runExample() throws Exception { + log.trace("Executing Template Method Pattern Implementation"); + + AbstractClass a = new ConcreteClassA(); + log.trace(" " + a.templateMethod()); + + AbstractClass b = new ConcreteClassB(); + log.trace(" " + b.templateMethod()); + } +} diff --git a/src/test/java/com/penapereira/example/constructs/templatemethod/TemplateMethodExampleRunnerTests.java b/src/test/java/com/penapereira/example/constructs/templatemethod/TemplateMethodExampleRunnerTests.java new file mode 100644 index 0000000..d9159e6 --- /dev/null +++ b/src/test/java/com/penapereira/example/constructs/templatemethod/TemplateMethodExampleRunnerTests.java @@ -0,0 +1,10 @@ +package com.penapereira.example.constructs.templatemethod; + +import org.junit.jupiter.api.Test; + +class TemplateMethodExampleRunnerTests { + @Test + void runExampleRuns() throws Exception { + new TemplateMethodExampleRunner().runExample(); + } +} diff --git a/src/test/java/com/penapereira/example/constructs/templatemethod/TemplateMethodTests.java b/src/test/java/com/penapereira/example/constructs/templatemethod/TemplateMethodTests.java new file mode 100644 index 0000000..5cebd6b --- /dev/null +++ b/src/test/java/com/penapereira/example/constructs/templatemethod/TemplateMethodTests.java @@ -0,0 +1,14 @@ +package com.penapereira.example.constructs.templatemethod; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +class TemplateMethodTests { + @Test + void templateMethodRunsSteps() { + AbstractClass a = new ConcreteClassA(); + assertEquals("A step one then A step two", a.templateMethod()); + AbstractClass b = new ConcreteClassB(); + assertEquals("B step one then B step two", b.templateMethod()); + } +}