Java设计模式之模板方法模式Template Method Pattern详解
概述
模板方法模式是一种行为设计模式。在该模式中,有一个抽象类作为模板,其中定义了算法的骨架,具体实现延迟到子类中。这种模式属于行为型模式。
在模板方法模式中,父类定义一个模板方法,该方法作为算法的骨架,而实际的子类实现会覆盖其中的某些步骤,但是整个算法的骨架不会改变。
实现
模板方法模式包含以下角色:
- 抽象类(Abstract Class):定义一个模板方法和一些抽象方法。
- 具体类(Concrete Class):实现抽象类中的抽象方法,并覆盖父类中的模板方法中已有的部分逻辑。
抽象类
在抽象类中,定义一个模板方法,该方法中会调用一系列抽象方法。例如:
public abstract class AbstractClass {
final void templateMethod(){
firstAbstractOperation();
secondAbstractOperation();
thirdAbstractOperation();
}
abstract void firstAbstractOperation();
abstract void secondAbstractOperation();
abstract void thirdAbstractOperation();
}
在这个例子中,我们定义了一个抽象类 AbstractClass
,其中 templateMethod()
方法是具体算法的骨架。在这个方法中,我们调用了三个抽象方法:firstAbstractOperation()
、secondAbstractOperation()
和 thirdAbstractOperation()
。
具体类
在具体类中,我们要实现抽象类中的所有抽象方法,并覆盖父类中的模板方法的已有部分逻辑。例如:
public class ConcreteClass extends AbstractClass {
void firstAbstractOperation() {
System.out.println("ConcreteClass firstAbstractOperation");
}
void secondAbstractOperation() {
System.out.println("ConcreteClass secondAbstractOperation");
}
void thirdAbstractOperation() {
System.out.println("ConcreteClass thirdAbstractOperation");
}
}
在这个例子中,我们定义了一个具体类 ConcreteClass
,并实现了抽象类中的三个抽象方法。这些方法将分别被 templateMethod()
调用。
例子
下面通过两个例子来说明模板方法模式的应用。
例子1:煮咖啡和茶
我们假设有一个咖啡制作过程,又有一个茶制作过程,这两个过程有一些共同的步骤。例如,都需要将水煮沸、将水倒入杯子中等等。
我们可以使用模板方法模式来实现这个例子。首先,我们定义一个抽象类 Beverage
,其中 prepareRecipe()
方法是模板方法:
public abstract class Beverage {
// 模板方法
public final void prepareRecipe() {
boilWater();
brew();
pourInCup();
addCondiments();
}
void boilWater() {
System.out.println("Boiling water");
}
void pourInCup() {
System.out.println("Pouring into cup");
}
abstract void brew();
abstract void addCondiments();
}
在 Beverage
类中,我们定义了一个模板方法 prepareRecipe()
,在这个方法中,我们定义了几个步骤:boilWater()
、brew()
、pourInCup()
和 addCondiments()
。
接下来,我们定义两个具体类 Coffee
和 Tea
,这两个类分别对应咖啡制作和茶制作两个过程:
public class Coffee extends Beverage {
void brew() {
System.out.println("Dripping Coffee through filter");
}
void addCondiments() {
System.out.println("Adding Sugar and Milk");
}
}
public class Tea extends Beverage {
void brew() {
System.out.println("Steeping the tea");
}
void addCondiments() {
System.out.println("Adding Lemon");
}
}
在 Coffee
和 Tea
类中,我们分别实现了 brew()
和 addCondiments()
两个抽象方法,这些方法将在 prepareRecipe()
中被调用。
现在,我们可以使用这些类来制作咖啡和茶:
Beverage coffee = new Coffee();
coffee.prepareRecipe();
Beverage tea = new Tea();
tea.prepareRecipe();
输出结果如下:
Boiling water
Dripping Coffee through filter
Pouring into cup
Adding Sugar and Milk
Boiling water
Steeping the tea
Pouring into cup
Adding Lemon
从输出结果可以看出,咖啡和茶的制作过程中,都共用了 Beverage
类中定义的一些步骤。
例子2:父母教孩子写作业
我们假设有一个父母教孩子写作业的场景,父母要求孩子按照以下步骤来写作业:
- 读懂题目。
- 划分大纲。
- 编写思维导图。
- 撰写正文。
- 检查错误并提交。
我们可以使用模板方法模式来实现这个例子。首先,我们定义一个抽象类 Homework
,其中 doHomework()
方法是模板方法:
public abstract class Homework {
// 模板方法
public final void doHomework() {
readQuestion();
makeOutline();
writeMindMap();
writeContents();
checkErrors();
}
void readQuestion() {
System.out.println("Read the homework question");
}
void checkErrors() {
System.out.println("Check errors and submit the homework");
}
abstract void makeOutline();
abstract void writeMindMap();
abstract void writeContents();
}
在 Homework
类中,我们定义了一个模板方法 doHomework()
,在这个方法中,我们定义了几个步骤:readQuestion()
、makeOutline()
、writeMindMap()
、writeContents()
和 checkErrors()
。
接下来,我们定义两个具体类 MathHomework
和 EnglishHomework
,这两个类分别对应数学作业和英语作业:
public class MathHomework extends Homework {
void makeOutline() {
System.out.println("Make an outline of the math homework");
}
void writeMindMap() {
System.out.println("Write a mind map for the math homework");
}
void writeContents() {
System.out.println("Write the contents of the math homework");
}
}
public class EnglishHomework extends Homework {
void makeOutline() {
System.out.println("Make an outline of the English homework");
}
void writeMindMap() {
System.out.println("Write a mind map for the English homework");
}
void writeContents() {
System.out.println("Write the contents of the English homework");
}
}
在 MathHomework
和 EnglishHomework
类中,我们分别实现了 makeOutline()
、writeMindMap()
和 writeContents()
三个抽象方法,这些方法将在 doHomework()
中被调用。
现在,我们可以使用这些类来教孩子写作业:
Homework mathHomework = new MathHomework();
mathHomework.doHomework();
Homework englishHomework = new EnglishHomework();
englishHomework.doHomework();
输出结果如下:
Read the homework question
Make an outline of the math homework
Write a mind map for the math homework
Write the contents of the math homework
Check errors and submit the homework
Read the homework question
Make an outline of the English homework
Write a mind map for the English homework
Write the contents of the English homework
Check errors and submit the homework
从输出结果可以看出,父母教孩子写数学作业和英语作业过程中,都共用了 Homework
类中定义的一些步骤。
总结
模板方法模式是一种常用的设计模式,它可以将具体实现延迟到子类中,从而使算法的骨架不会改变。在实际应用中,我们可以根据具体的场景,使用这种模式来提高代码的复用性和可维护性。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java设计模式之模板方法模式Template Method Pattern详解 - Python技术站