From 45052c65f546d81867f7f3fcd875b6ba9e9dd5f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Wed, 22 May 2024 11:07:53 +0300 Subject: [PATCH] docs: update template method --- template-method/README.md | 80 +++++++++++++------ .../templatemethod/StealingMethodTest.java | 2 +- 2 files changed, 55 insertions(+), 27 deletions(-) diff --git a/template-method/README.md b/template-method/README.md index f64617d2a..2e86737c7 100644 --- a/template-method/README.md +++ b/template-method/README.md @@ -3,42 +3,40 @@ title: Template method category: Behavioral language: en tag: - - Gang of Four + - Abstraction + - Code simplification + - Decoupling + - Extensibility + - Gang of Four + - Inheritance + - Object composition + - Polymorphism + - Reusability --- ## Intent -Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template -Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's -structure. +Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure. ## Explanation Real-world example -> The general steps in stealing an item are the same. First, you pick the target, next you confuse -> him somehow and finally, you steal the item. However, there are many ways to implement these -> steps. +> A real-world analogy for the Template Method pattern can be seen in the preparation of a cup of tea or coffee. The overall process (algorithm) is the same: boil water, brew the beverage, pour into cup, and add condiments. However, the specific steps of brewing the beverage differ. For tea, you steep the tea leaves in hot water, while for coffee, you brew ground coffee beans. The Template Method pattern encapsulates the invariant steps of the process (boiling water, pouring, adding condiments) in a base class, while allowing subclasses to define the specific brewing steps, thus ensuring the overall structure of making a hot drink is consistent while allowing customization where needed. In plain words -> Template Method pattern outlines the general steps in the parent class and lets the concrete child -> implementations define the details. +> Template Method pattern outlines the general steps in the parent class and lets the concrete child implementations define the details. Wikipedia says -> In object-oriented programming, the template method is one of the behavioral design patterns -> identified by Gamma et al. in the book Design Patterns. The template method is a method in a -> superclass, usually an abstract superclass, and defines the skeleton of an operation in terms of -> a number of high-level steps. These steps are themselves implemented by additional helper methods -> in the same class as the template method. +> In object-oriented programming, the template method is one of the behavioral design patterns identified by Gamma et al. in the book Design Patterns. The template method is a method in a superclass, usually an abstract superclass, and defines the skeleton of an operation in terms of a number of high-level steps. These steps are themselves implemented by additional helper methods in the same class as the template method. **Programmatic Example** -Let's first introduce the template method class along with its concrete implementations. -To make sure that subclasses don’t override the template method, the template method (in our case -method `steal`) should be declared `final`, otherwise the skeleton defined in the base class could -be overridden in subclasses. +Our programmatic example is about thieves and stealing. The general steps in stealing an item are the same. First, you pick the target, next you confuse him somehow and finally, you steal the item. However, there are many ways to implement these steps. + +Let's first introduce the template method class `StealingMethod` along with its concrete implementations `SubtleMethod` and `HitAndRunMethod`. To make sure that subclasses don’t override the template method, the template method (in our case method `steal`) should be declared `final`, otherwise the skeleton defined in the base class could be overridden in subclasses. ```java @@ -128,9 +126,20 @@ And finally, we show how the halfling thief utilizes the different stealing meth thief.steal(); ``` +The program output: + +``` +11:06:01.721 [main] INFO com.iluwatar.templatemethod.StealingMethod -- The target has been chosen as old goblin woman. +11:06:01.723 [main] INFO com.iluwatar.templatemethod.HitAndRunMethod -- Approach the old goblin woman from behind. +11:06:01.723 [main] INFO com.iluwatar.templatemethod.HitAndRunMethod -- Grab the handbag and run away fast! +11:06:01.723 [main] INFO com.iluwatar.templatemethod.StealingMethod -- The target has been chosen as shop keeper. +11:06:01.723 [main] INFO com.iluwatar.templatemethod.SubtleMethod -- Approach the shop keeper with tears running and hug him! +11:06:01.723 [main] INFO com.iluwatar.templatemethod.SubtleMethod -- While in close contact grab the shop keeper's wallet. +``` + ## Class diagram -![alt text](./etc/template_method_urm.png "Template Method") +![Template Method](./etc/template_method_urm.png "Template Method") ## Applicability @@ -142,16 +151,35 @@ The Template Method pattern should be used ## Tutorials -* [Template-method Pattern Tutorial](https://www.journaldev.com/1763/template-method-design-pattern-in-java) +* [Template Method Design Pattern In Java - Digital Ocean](https://www.digitalocean.com/community/tutorials/template-method-design-pattern-in-java) ## Known uses -* [javax.servlet.GenericServlet.init](https://jakarta.ee/specifications/servlet/4.0/apidocs/javax/servlet/GenericServlet.html#init--): -Method `GenericServlet.init(ServletConfig config)` calls the parameterless method `GenericServlet.init()` which is intended to be overridden in subclasses. -Method `GenericServlet.init(ServletConfig config)` is the template method in this example. +* Java's AbstractList and AbstractSet classes in the Collections Framework use the Template Method pattern to define common algorithms for list and set operations. +* Frameworks like JUnit use Template Method to define the setup and teardown process in test cases. + +## Consequences + +Benefits: + +* Promotes code reuse by defining invariant parts of an algorithm in a base class. +* Simplifies code maintenance by encapsulating common behavior in one place. +* Enhances flexibility by allowing subclasses to override specific steps of an algorithm. + +Trade-offs: + +* Can lead to an increase in the number of classes, making the system more complex. +* Requires careful design to ensure that the steps exposed to subclasses are useful and meaningful. + +## Related Patterns + +* [Factory Method](https://java-design-patterns.com/patterns/factory-method/): Often used with Template Method to create objects needed for specific steps of the algorithm. +* [Strategy](https://java-design-patterns.com/patterns/strategy/): While Template Method defines the skeleton of an algorithm and lets subclasses implement specific steps, the Strategy Pattern defines a family of algorithms and makes them interchangeable. +* [Subclass Sandbox](https://java-design-patterns.com/patterns/subclass-sandbox/): Complements Template Method by ensuring that subclasses can safely override specific steps of an algorithm without causing unintended side effects. ## Credits -* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) -* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b) -* [Refactoring to Patterns](https://www.amazon.com/gp/product/0321213351/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321213351&linkCode=as2&tag=javadesignpat-20&linkId=2a76fcb387234bc71b1c61150b3cc3a7) +* [Design Patterns: Elements of Reusable Object-Oriented Software](https://amzn.to/3w0pvKI) +* [Effective Java](https://amzn.to/4cGk2Jz) +* [Head First Design Patterns: Building Extensible and Maintainable Object-Oriented Software](https://amzn.to/49NGldq) +* [Refactoring to Patterns](https://amzn.to/3VOO4F5) diff --git a/template-method/src/test/java/com/iluwatar/templatemethod/StealingMethodTest.java b/template-method/src/test/java/com/iluwatar/templatemethod/StealingMethodTest.java index c8bc832e9..dc648c96c 100644 --- a/template-method/src/test/java/com/iluwatar/templatemethod/StealingMethodTest.java +++ b/template-method/src/test/java/com/iluwatar/templatemethod/StealingMethodTest.java @@ -146,7 +146,7 @@ public abstract class StealingMethodTest { assertEquals(3, appender.getLogSize()); } - private class InMemoryAppender extends AppenderBase { + private static class InMemoryAppender extends AppenderBase { private final List log = new LinkedList<>(); public InMemoryAppender() {