模板方法设计模式
背景和价值
模板方法是面向对象中的一个行为设计模式,属于经典的设计模式之一。它的核心思想是在父类中定义一个算法的骨架,将一些步骤延迟到子类中实现,从而让子类在不改变算法结构的情况下重定义某些特定步骤。
概念
钩子机制:
钩子机制(Hook Mechanism) 是一种设计模式,允许在程序的特定位置(“钩子点”)插入自定义逻辑,而无需修改原有代码的结构。它的核心思想是“预留扩展点”,让外部代码(子类或第三方模块)能够灵活地“挂钩”到系统的运行流程中,从而实现功能的动态扩展或个性化定制。
模板方法的核心要素
-
抽象类(Abstract Class)
• 定义算法的骨架(模板方法)和不可变的具体方法。
• 声明抽象方法(子类必须实现的关键步骤)和钩子方法(可选的默认实现)。 -
模板方法(Template Method)
• 父类中定义的final
方法,描述算法的整体流程。
• 调用自身或其他抽象方法/钩子方法。 -
抽象方法(Abstract Method)
• 需要子类实现的步骤,没有默认实现。 -
钩子方法(Hook Method)
• 父类中提供默认实现的方法,子类可选择覆盖以改变行为。
总结
模板方法模式通过分离不变与可变逻辑,提高了代码复用性和扩展性。正确使用时:
- 在抽象类中定义算法骨架;
- 将可变步骤抽象为方法(强制子类实现);
- 为可选步骤提供钩子方法(默认实现);
- 确保子类遵循父类的约束条件。
正确使用的步骤
1. 识别固定流程与可变部分
• 固定流程:所有子类必须遵循的通用逻辑(如日志记录、事务管理等)。
• 可变部分:不同子类需要自定义的逻辑(如支付渠道差异、业务规则不同)。
2. 定义抽象类与模板方法
public abstract class AbstractClass {
// 模板方法:固定流程
public final void templateMethod() {
step1(); // 固定步骤
step2WithHook(); // 可变步骤(钩子方法)
step3(); // 固定步骤
}
// 抽象方法:子类必须实现
protected abstract void step1();
// 钩子方法:子类可选实现
protected void step2WithHook() {
System.out.println("Default implementation of step2");
}
// 具体方法:固定逻辑
private void step3() {
System.out.println("Fixed step3 logic");
}
}
3. 实现子类
public class ConcreteClassA extends AbstractClass {
@Override
protected void step1() {
System.out.println("ConcreteClassA: Step1 implementation");
}
// 选择覆盖钩子方法
@Override
protected void step2WithHook() {
System.out.println("ConcreteClassA: Custom step2");
}
}
public class ConcreteClassB extends AbstractClass {
@Override
protected void step1() {
System.out.println("ConcreteClassB: Step1 implementation");
}
// 使用默认钩子方法
// (无覆盖,执行父类默认逻辑)
}
4. 调用模板方法
public class Client {
public static void main(String[] args) {
AbstractClass instanceA = new ConcreteClassA();
instanceA.templateMethod();
AbstractClass instanceB = new ConcreteClassB();
instanceB.templateMethod();
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端