模板方法设计模式

背景和价值

模板方法是面向对象中的一个行为设计模式,属于经典的设计模式之一。它的核心思想是在父类中定义一个算法的骨架,将一些步骤延迟到子类中实现,从而让子类在不改变算法结构的情况下重定义某些特定步骤。

概念

钩子机制:
钩子机制(Hook Mechanism)​​ 是一种设计模式,允许在程序的特定位置(“钩子点”)插入自定义逻辑,而无需修改原有代码的结构。它的核心思想是​“预留扩展点”​,让外部代码(子类或第三方模块)能够灵活地“挂钩”到系统的运行流程中,从而实现功能的动态扩展或个性化定制。

模板方法的核心要素

  1. 抽象类(Abstract Class)
    • 定义算法的骨架(模板方法)和不可变的具体方法。
    • 声明抽象方法(子类必须实现的关键步骤)和钩子方法(可选的默认实现)。

  2. 模板方法(Template Method)
    • 父类中定义的 final 方法,描述算法的整体流程。
    • 调用自身或其他抽象方法/钩子方法。

  3. 抽象方法(Abstract Method)
    • 需要子类实现的步骤,没有默认实现。

  4. 钩子方法(Hook Method)
    • 父类中提供默认实现的方法,子类可选择覆盖以改变行为。

总结

模板方法模式通过分离不变与可变逻辑,提高了代码复用性和扩展性。正确使用时:

  1. 在抽象类中定义算法骨架;
  2. 将可变步骤抽象为方法(强制子类实现);
  3. 为可选步骤提供钩子方法(默认实现);
  4. 确保子类遵循父类的约束条件。

正确使用的步骤

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();
    }
}

参考资料

posted @   向着朝阳  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端
点击右上角即可分享
微信分享提示