当谈到模板方法模式时,在面向对象的编程中,它是一种行为设计模式。模板方法模式定义了一个操作中的算法骨架,将一些步骤延迟到子类中实现,使得子类可以在不改变算法结构的情况下重新定义算法中的某些步骤。
使用模板方法模式的主要目的是将通用的算法步骤抽象到父类中,然后通过具体的子类来实现这些步骤的具体细节。这样可以避免代码的重复,并且使得算法的结构更加清晰可见。
模板方法模式的使用场景通常是在以下情况下:
当有一个通用的算法结构,但其中的某些步骤的具体实现可能会有所不同时,可以使用模板方法模式。例如,一个建筑公司可能有多个具体的建筑项目,但它们共享相同的施工过程。
当需要在不改变算法结构的情况下,通过子类来扩展或修改某些步骤的实现时,可以使用模板方法模式。
假设有一个叫做Tom的人,他是一名音乐家,他每天都有一套固定的音乐表演流程。这个流程包括三个步骤:准备乐器、演奏音乐、道别观众。
Tom为了能够更好地组织自己的表演,决定使用模板方法模式。他创建了一个名为Musician的抽象类,其中定义了一个名为performance的模板方法。
开始:
Tom首先准备乐器,这是表演的第一步。在抽象类Musician中,他定义了一个名为prepareInstrument的抽象方法,他知道这是一个必须由不同的音乐家来具体实现的步骤。
然后:
Tom开始演奏音乐,这是表演的第二步。在抽象类Musician中,他定义了一个名为playMusic的具体方法,这个方法有一个默认的实现,其中包含了一些通用的演奏操作。
最后:
Tom道别观众,这是表演的最后一步。在抽象类Musician中,他定义了一个名为farewellAudience的抽象方法,他知道每个音乐家都有不同的方式来与观众道别。
Tom创建了两个具体的子类:Pianist和Violinist,他们都继承了Musician类。在这两个子类中,他们分别实现了抽象方法prepareInstrument和farewellAudience。
当Tom要进行表演时,他选择具体的子类来实例化,并调用performance方法。这个方法按照抽象类中定义的顺序依次调用了prepareInstrument、playMusic和farewellAudience方法。
通过模板方法模式,Tom可以轻松地组织自己的音乐表演流程,而不必关心每个具体步骤的细节。他可以根据需要选择不同的子类来实现特定的步骤,从而实现了代码的复用和灵活性的提高。
// 抽象类
abstract class Musician {
// 模板方法
public final void performance() {
prepareInstrument();
playMusic();
farewellAudience();
}
// 抽象方法,子类必须实现
protected abstract void prepareInstrument();
// 具体方法,子类可以选择性实现
protected void playMusic() {
System.out.println("Playing music");
}
// 抽象方法,子类必须实现
protected abstract void farewellAudience();
}
// 具体类:钢琴家
class Pianist extends Musician {
@Override
protected void prepareInstrument() {
System.out.println("Preparing piano");
}
@Override
protected void farewellAudience() {
System.out.println("Farewell, audience");
}
}
// 具体类:小提琴家
class Violinist extends Musician {
@Override
protected void prepareInstrument() {
System.out.println("Preparing violin");
}
@Override
protected void farewellAudience() {
System.out.println("Farewell, audience");
}
}
// 客户端代码
public class Main {
public static void main(String[] args) {
Musician pianist = new Pianist();
pianist.performance();
Musician violinist = new Violinist();
violinist.performance();
}
}
在上面的示例中,Musician是一个抽象类,其中定义了一个模板方法performance,这个方法包含了一系列的表演步骤调用。其中,prepareInstrument和farewellAudience是抽象方法,需要在具体的子类中实现;而playMusic是一个具体方法,可以选择性地在子类中实现。
Pianist和Violinist是具体的子类,它们继承了Musician并实现了其中的抽象方法。通过调用performance方法,可以看到具体子类中的实现细节按照抽象类中定义的算法骨架被执行。
这样,通过模板方法模式,Tom可以按照固定的流程进行音乐表演,而不必关心每个具体步骤的细节。他可以根据需要选择不同的子类来实现特定的步骤,从而实现了代码的复用和灵活性的提高。