模板方法(Template Method)

模板方法(Template Method)是一种行为设计模式,它定义了一个算法的骨架,将算法的某些步骤延迟到子类中实现。这样,子类可以在不改变算法整体结构的情况下,重新定义算法的某些特定步骤。以下从几个方面详细介绍模板方法模式。

模式结构

模板方法模式主要包含以下两个角色:

  • 抽象类(Abstract Class):定义了模板方法和一些抽象方法。模板方法是一个具体方法,它定义了算法的骨架,调用了抽象方法和具体方法;抽象方法则由子类实现,用于完成算法中可变的部分。
  • 具体子类(Concrete Class):继承抽象类,实现抽象类中的抽象方法,完成算法中特定步骤的具体实现。

代码示例

以下是一个简单的代码示例,以制作饮料为例,展示模板方法模式的应用:

// 抽象类:饮料制作
abstract class BeverageMaker {
    // 模板方法:制作饮料的整体流程
    public final void makeBeverage() {
        boilWater();
        brew();
        pourInCup();
        if (customerWantsCondiments()) {
            addCondiments();
        }
    }

    // 具体方法:烧水
    private void boilWater() {
        System.out.println("Boiling water");
    }

    // 抽象方法:冲泡
    abstract void brew();

    // 具体方法:倒入杯子
    private void pourInCup() {
        System.out.println("Pouring into cup");
    }

    // 钩子方法:是否添加调料,子类可以重写该方法
    boolean customerWantsCondiments() {
        return true;
    }

    // 抽象方法:添加调料
    abstract void addCondiments();
}

// 具体子类:咖啡制作
class CoffeeMaker extends BeverageMaker {
    @Override
    void brew() {
        System.out.println("Dripping coffee through filter");
    }

    @Override
    void addCondiments() {
        System.out.println("Adding sugar and milk");
    }

    @Override
    boolean customerWantsCondiments() {
        // 可以根据用户输入决定是否添加调料
        return false;
    }
}

// 具体子类:茶制作
class TeaMaker extends BeverageMaker {
    @Override
    void brew() {
        System.out.println("Steeping the tea");
    }

    @Override
    void addCondiments() {
        System.out.println("Adding lemon");
    }
}

// 客户端代码
public class TemplateMethodExample {
    public static void main(String[] args) {
        BeverageMaker coffeeMaker = new CoffeeMaker();
        coffeeMaker.makeBeverage();

        System.out.println();

        BeverageMaker teaMaker = new TeaMaker();
        teaMaker.makeBeverage();
    }
}

代码解释

  • 抽象类 BeverageMaker
    • makeBeverage() 是模板方法,它定义了制作饮料的整体流程,包括烧水、冲泡、倒入杯子和添加调料等步骤。
    • boilWater()pourInCup() 是具体方法,它们的实现是固定的。
    • brew()addCondiments() 是抽象方法,由具体子类实现。
    • customerWantsCondiments() 是钩子方法,子类可以根据需要重写该方法,决定是否执行添加调料的步骤。
  • 具体子类 CoffeeMakerTeaMaker
    • 实现了 brew()addCondiments() 方法,完成了咖啡和茶的冲泡和添加调料的具体操作。
    • CoffeeMaker 重写了 customerWantsCondiments() 方法,返回 false,表示不添加调料。
  • 客户端代码
    • 创建了 CoffeeMakerTeaMaker 的实例,并调用 makeBeverage() 方法制作饮料。

优点

  • 代码复用:将算法的公共部分提取到抽象类中,避免了代码的重复编写。
  • 可扩展性:子类可以根据需要重写抽象方法,实现算法的特定步骤,而不影响算法的整体结构。
  • 符合开闭原则:对扩展开放,对修改关闭。当需要添加新的饮料类型时,只需要创建新的具体子类,而不需要修改抽象类和其他子类的代码。

缺点

  • 类的数量增加:随着具体子类的增加,类的数量会增多,导致系统的复杂度增加。
  • 灵活性受限:模板方法模式的算法骨架是固定的,子类只能在特定的步骤上进行扩展,可能无法满足一些复杂的需求。

应用场景

  • 算法的整体步骤固定,但某些步骤的实现可能不同:例如,文件处理流程、数据库操作流程等。
  • 多个子类有公共的行为,但某些行为的实现不同:例如,不同类型的报表生成、不同类型的游戏关卡等。
Java设计模式 文章被收录于专栏

设计模式是软件开发中针对反复出现的问题所总结归纳出的通用解决方案,它可以帮助开发者更高效地构建软件系统,提升代码的可维护性、可扩展性和可复用性。

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务