模板方法模式(Template Method Pattern)是一种行为型设计模式,它定义了一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重新定义算法的某些特定步骤。
主要角色
-
抽象类(Abstract Class):定义了一个或多个抽象操作,以便让子类实现。这些抽象操作叫做基本操作,它们是一个顶级逻辑的一部分,而顶级逻辑的定义则在一个叫做模板方法的方法中。
-
具体子类(Concrete Classes):实现父类所定义的一个或多个抽象方法。
-
模板方法(Template Method):这是定义在抽象类中的具体方法。模板方法定义了算法的骨架,它会调用一个或多个抽象方法。
工作原理
- 模板方法模式通过定义一个操作中的算法的骨架,将一些步骤延迟到子类中实现。
- 模板方法使得子类可以在不改变算法结构的前提下,重新定义算法的某些步骤。
- 模板方法模式是一种代码复用技术,它在类库设计中尤为重要,它提取了类库中的公共行为,将公共行为放在父类中,而通过钩子(Hook)方法让子类覆盖以实现特定的行为。
优点
- 封装不变部分,扩展可变部分:把认为是不变部分的算法封装在抽象父类中,而可变部分则允许子类继承去实现。
- 提高代码复用性:不需要改变算法的结构即可重新定义算法的某些特定步骤。
- 符合开闭原则:对扩展开放,对修改关闭,增加新的功能符合开闭原则。
缺点
- 需要为每一个基本方法都提供一个钩子(Hook)方法,这可能会增加很多子类,过度设计。
- 在使用模板方法模式时要小心不要违反里氏替换原则(Liskov Substitution Principle)。
示例
我们将以一个简单的游戏角色创建过程为例,展示模板方法模式的应用。在这个例子中,我们将有一个游戏角色基类(GameCharacter
),它定义了一个创建角色的算法骨架,包括初始化属性、选择武器和装备防具等步骤。然后,我们将有两个具体的子类,分别代表战士(Warrior
)和法师(Mage
),它们将实现这些步骤中的特定细节。
// 抽象类
abstract class GameCharacter {
// 模板方法
final void createCharacter() {
initializeAttributes();
chooseWeapon();
equipArmor();
}
// 基本方法,由子类实现
abstract void initializeAttributes();
abstract void chooseWeapon();
abstract void equipArmor();
// 可以选择添加一些通用方法或钩子方法
void displayCharacter() {
System.out.println("Character created successfully!");
}
}
// 具体子类:战士
class Warrior extends GameCharacter {
@Override
void initializeAttributes() {
System.out.println("Initializing Warrior attributes...");
// 设置力量、耐力等属性
}
@Override
void chooseWeapon() {
System.out.println("Warrior chooses a sword as his weapon.");
}
@Override
void equipArmor() {
System.out.println("Warrior equips heavy armor.");
}
}
// 具体子类:法师
class Mage extends GameCharacter {
@Override
void initializeAttributes() {
System.out.println("Initializing Mage attributes...");
// 设置智力、魔法值等属性
}
@Override
void chooseWeapon() {
System.out.println("Mage chooses a staff as his weapon.");
}
@Override
void equipArmor() {
System.out.println("Mage equips robes for armor.");
}
}
// 客户端代码
public class TemplateMethodPatternDemo2 {
public static void main(String[] args) {
GameCharacter warrior = new Warrior();
warrior.createCharacter();
warrior.displayCharacter();
GameCharacter mage = new Mage();
mage.createCharacter();
mage.displayCharacter();
}
}
在这个例子中,GameCharacter
类定义了一个创建游戏角色的算法骨架,即模板方法createCharacter
。这个方法调用了三个抽象方法:initializeAttributes
、chooseWeapon
和equipArmor
,这些方法由具体的子类(Warrior
和Mage
)来实现,以提供创建不同类型角色所需的特定细节。
通过模板方法模式,我们能够在不改变创建角色算法结构的前提下,通过扩展具体的子类来创建不同类型的游戏角色。此外,我们还可以在GameCharacter
类中添加更多的通用方法或钩子方法,以进一步增强该模式的灵活性和可扩展性。