This article describes the Template Method pattern. You should always understand the difference between an abstract class and an interface. Even if you skip this step and enter the design pattern, you will not be able to master it. Here I think the article will be very helpful, so please take a look.
In Japanese, it is ** type **. I think that work will be improved by creating a ** template ** to some extent when composing an email. The same can be said for programs.
A method of extracting the common part of processing into an abstract class and implementing unique processing in a concrete class. To put it more simply, it can be used when you want to ** share similar flow processing **. I think this * flow * is important. Instead of just bringing the processing that can be shared to the abstract class The best part of this pattern is to extract ** processing flow ** into an abstract class as a template (type).
I think you can use this pattern in the following cases. ** When the processing flow of multiple concrete classes is similar, such as "pre-processing, main processing, post-processing" **
It is difficult to determine when this can be used, and it is the most important part, so the program you wrote once, I think you should think about it by looking at the published source code.
Let's use the template method pattern using a student day and a working day as an example.
student | society | |
---|---|---|
Get up | Get up | ← Same behavior |
Sleep twice | Preparation | ← Different behavior |
play | jobs | ← Different behavior |
Going to bed | Going to bed | ← Same behavior |
I wrote the daily behavior patterns (types) of students and working people. You can use the template method pattern when the patterns (types) are similar like this! If you write the flow of human life in an abstract class (implement common actions) and implement different actions in each concrete class, it is easy, but the template method pattern is completed.
Let's actually implement it using the one shown above as an example.
Implement the flow of human life with an abstract class. Waking up and going to bed are the same actions, so we will implement them in an abstract class.
Human.java
public abstract class Human {
public void startDay(){
getUp();
preAction();
mainAction();
sleep();
}
protected abstract void mainAction();
protected abstract void preAction();
private void getUp(){
System.out.println("Get up");
}
private void sleep(){
System.out.println("Going to bed");
}
}
We will implement student-specific double sleep and play in this concrete class.
Student.java
public class Student extends Human{
@Override
protected void mainAction() {
System.out.println("Sleep twice");
}
@Override
protected void preAction() {
System.out.println("play");
}
}
This concrete class implements the preparation and work peculiar to working people.
WorkingAdult.java
public class WorkingAdult extends Human{
@Override
protected void mainAction() {
System.out.println("Preparation");
}
@Override
protected void preAction() {
System.out.println("jobs");
}
}
Finally, create a class that calls these above classes. Just start the day with new students and working people
Main.java
public class Main {
public static void main(String[] arg){
Human student = new Student();
Human worker = new WorkingAdult();
System.out.println("**student**");
student.startDay();
System.out.println("**society**");
worker.startDay();
}
}
/*
**student**
Get up
play
Sleep twice
Going to bed
**society**
Get up
jobs
Preparation
Going to bed
*/
how was it? It was unexpectedly easy! Rather, I just brought common processing to an abstract class !? ** What I want you to understand here is that I brought the process flow to an abstract class. ** **
From here, it's a little advanced.
There is a Composed Method pattern, but it just extracts the method and Let's improve the readability until you can read the process! !! The technique. Combining this Composed Method pattern with the Template Method pattern What good is there?
For example, the processing is similar, but it is slightly different and cannot be shared. .. .. So when you can't use the Template Method pattern, you can combine this method.
Let's take the process of making coffee and tea as an example.
Class to make coffee
Coffee.java
public class Coffee {
public void makeCoffee(){
createHotWater();
System.out.println("Add coffee powder");
waiting();
}
private void createHotWater() {
System.out.println("Make boiling water");
}
private void waiting(){
System.out.println("wait");
}
}
Class to make tea
Tea.java
public class Tea {
public void makeCoffee(){
createHotWater();
System.out.println("Add black tea powder");
waiting();
}
private void createHotWater() {
System.out.println("Make boiling water");
}
private void waiting(){
System.out.println("wait");
}
}
Oh! !! !! "Make boiling water, make coffee or tea, wait" It's a similar process! !! Let's use the Template Method pattern! !! !! !! I want you to try it out. You may notice it.
The parts that are not methodized, "add corpi powder" and "add tea powder", remain as they are. Cannot be standardized. Here comes the Composed Method pattern!
Let's rewrite the coffee class as follows. Just extracted a piece of code into the putPowder method
Coffee.java
public class Coffee {
public void makeCoffee(){
createHotWater();
putPowder();
waiting();
}
protected void putPowder() {
System.out.println("Add coffee powder");
}
private void createHotWater() {
System.out.println("Make boiling water");
}
private void waiting(){
System.out.println("wait");
}
}
Let's rewrite the tea class as follows. Just extracted a piece of code into the putPowder method
Tea.java
public class Tea {
public void makeCoffee(){
createHotWater();
putPowder();
waiting();
}
protected void putPowder() {
System.out.println("Add coffee powder");
}
private void createHotWater() {
System.out.println("Make boiling water");
}
private void waiting(){
System.out.println("wait");
}
}
At this point, all you have to do is raise the method to an abstract method and implement the concrete processing in a concrete class.
Did you understand the purpose of the Template Method pattern? It's very simple to use when creating a new one, but if you want to refactor your existing code, It is unexpectedly difficult to determine that "somewhere can be shared".
Also, in abstract classes, it is better to use abstract method names as much as possible. If you write a unique name when the number of concrete classes increases steadily, The processing content and the method name will not match.
Recommended Posts