# 模板方法模式

# 概念

模板方法模式是一种行为型设计模式,其核心思想是定义一个算法的骨架,允许子类在不改变算法结构的情况下重定义某些步骤。父类通过模板方法控制流程,子类通过实现抽象方法填充细节,实现反向控制结构(父类调用子类)。

# 作用

1.代码复用:将公共逻辑抽取到父类,避免重复代码。

2.扩展性:子类只需关注差异部分,符合开闭原则。

3.流程控制:父类固定核心流程,防止子类破坏执行顺序。

# 场景

1.多个类具有相似流程但部分步骤不同(如数据解析、文件处理)。

2.需要固定核心算法流程,允许子类扩展特定步骤。

3.框架设计(如Spring的JdbcTemplate)。

# 举例

// 饮料类
abstract class Beverage {
    // 准备食谱:模板方法 (final防止子类覆盖)
    public final void prepareRecipe() {
        // 烧开水
        boilWater();
        // 泡
        brew();
        // 倒入杯子
        pourInCup();
        // 是否加入调味剂
        if (customerWantsCondiments()) {
            addCondiments();
        }
    }

    // 固定步骤:烧开水
    private void boilWater() {
        System.out.println("烧开水");
    }
    // 固定步骤:倒入杯子
    private void pourInCup() {
        System.out.println("倒入杯子");
    }

    // 抽象方法(必须实现)
    abstract void brew();
    abstract void addCondiments();

    // 钩子方法(可选覆盖)
    boolean customerWantsCondiments() {
        return true;
    }
}
class Coffee extends Beverage {
    @Override
    void brew() {
        System.out.println("冲泡咖啡粉");
    }

    @Override
    void addCondiments() {
        System.out.println("加糖和牛奶");
    }

    @Override
    boolean customerWantsCondiments() {
        return false; // 示例:咖啡不要调料
    }
}
class Tea extends Beverage {
    @Override
    void brew() {
        System.out.println("浸泡茶叶");
    }

    @Override
    void addCondiments() {
        System.out.println("加柠檬");
    }
}

# 反例

class CoffeeWithoutPattern {
    public void makeCoffee() {
        System.out.println("烧开水");
        System.out.println("冲泡咖啡粉");
        System.out.println("倒入杯子");
        System.out.println("加糖和牛奶"); // 重复代码
    }
}
class TeaWithoutPattern {
    public void makeTea() {
        System.out.println("烧开水");       // 重复代码
        System.out.println("浸泡茶叶");
        System.out.println("倒入杯子");    // 重复代码
        System.out.println("加柠檬");
    }
}

不使用模板方法模式时,存在以下问题:

1.重复代码:烧开水、倒入杯子等公共步骤在多个类中重复实现。

2.维护困难:修改流程需改动所有相关类,成本高。

3.流程失控:子类可能遗漏步骤或改变执行顺序,破坏业务逻辑。

# 原理

模板方法模式通过父类定义算法骨架(模板方法),将可变步骤抽象为方法(抽象方法或钩子方法),子类通过实现这些方法填充细节。模板方法使用final修饰防止子类覆盖,确保核心流程统一;钩子方法提供默认实现,子类可选择性覆盖以调整行为。

# 缺点

1.增加类数量:每个差异步骤需对应一个子类,可能导致类爆炸。

2.父类耦合:父类修改可能影响所有子类,需谨慎设计抽象方法。

3.继承复杂度:过度使用可能导致继承层次过深,系统难以理解。

总结

模板方法模式通过父类控制流程、子类填充细节的方式,有效解决多类相似流程的代码复用问题,尤其适合需要严格流程控制的场景(如框架设计)。其核心价值在于统一算法结构、降低维护成本,但需注意避免过度继承导致的系统复杂度上升。



微信公众号

QQ交流群
原创网站开发,偏差难以避免。

如若发现错误,诚心感谢反馈。

愿你倾心相念,愿你学有所成。

愿你朝华相顾,愿你前程似锦。