模板方法模式

简介

模板方法模式(Template Method Pattern)又叫作模板模式,指定义一个操作中的算法的框架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤,属于行为型设计模式。

通用模板

  1. 创建抽象模板:抽象模板类,定义了一套算法框架/流程。

    java 复制代码
    // 抽象模板类
    public abstract class AbstractTemplate {
        protected void step1(){
            System.out.println("AbstractTemplate step1");
        }
    
        protected void step2(){
            System.out.println("AbstractTemplate step2");
        }
    
        protected void step3(){
            System.out.println("AbstractTemplate step3");
        }
       // 生命为final类型,避免子类对其覆写
        public final void templateMethod(){
            this.step1();
            this.step2();
            this.step3();
        }
    }
  2. 创建具体实现类:具体实现类,对算法框架/流程的某些步骤进行了实现。

    java 复制代码
    // 具体实现类A
    public class ConcreteA extends AbstractTemplate {
        @Override
        public void step1() {
            System.out.println("ConcreteA step1");
        }
    
        @Override
        public void step2() {
            System.out.println("ConcreteA step2");
        }
    
        @Override
        public void step3() {
            System.out.println("ConcreteA step3");
        }
    }
    java 复制代码
    // 具体实现类A
    public class ConcreteB extends AbstractTemplate {
        @Override
        public void step1() {
            System.out.println("ConcreteB step1");
        }
    
        @Override
        public void step2() {
            System.out.println("ConcreteB step2");
        }
    
        @Override
        public void step3() {
            System.out.println("ConcreteB step3");
        }
    }

模板测试

  1. 测试代码

    java 复制代码
    public class Client {
        public static void main(String[] args) {
            AbstractTemplate abc = new ConcreteA();
            abc.templateMethod();
            abc = new ConcreteB();
            abc.templateMethod();
        }
    }
  2. 结果

    java 复制代码
    ConcreteA step1
    ConcreteA step2
    ConcreteA step3
    ConcreteB step1
    ConcreteB step2
    ConcreteB step3

应用场景

当完成一个操作具有固定的流程时,由抽象固定流程步骤,具体步骤交给子类进行具体实现(固定的流程,不同的实现)。

模板方法模式适用于以下应用场景。

(1)一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。

(2)各子类中公共的行为被提取出来,集中到一个公共的父类中,从而避免代码重复。

优点

(1)利用模板方法将相同处理逻辑的代码放到抽象父类中,可以提高代码的复用性。

(2)将不同的算法逻辑分离到不同的子类中,通过对子类的扩展增加新的行为,提高代码的可扩展性。

(3)把不变的行为写在父类上,去除子类的重复代码,提供了一个很好的代码复用平台,符合开闭原则。

缺点

(1)每一个抽象类都需要一个子类来实现,这样导致类数量增加。

(2)类数量的增加,间接地增加了系统实现的复杂度。

(3)由于继承关系自身的缺点,如果父类添加新的抽象方法,则所有子类都要改一遍。

"生搬硬套"实战

场景描述

假设你是一位烘焙师傅,你经常需要制作各种蛋糕。尽管蛋糕的种类很多,但制作蛋糕的基本步骤是相似的:准备材料、混合材料、烘烤、装饰。这些步骤中有一些是固定的,而另一些可以根据具体的蛋糕种类进行调整。

代码开发
  1. 创建抽象模板(这里制作蛋糕模板类)

    java 复制代码
    // 制作蛋糕模板类
    public abstract class CakeBakingTemplate {
        // 模板方法,定义了制作蛋糕的整体流程
        public final void bakeCake() {
            prepareIngredients();
            mixIngredients();
            bake();
            decorate();
        }
    
        // 抽象方法,子类必须实现
        protected abstract void prepareIngredients();
    
        // 默认实现的方法,子类可以选择重写
        protected void mixIngredients() {
            System.out.println("在碗里混合配料。");
        }
    
        // 默认实现的方法,子类可以选择重写
        protected void bake() {
            System.out.println("在烤箱里烤蛋糕。");
        }
    
        // 默认实现的方法,子类可以选择重写
        protected void decorate() {
            System.out.println("用糖霜装饰蛋糕。");
        }
    }
  2. 创建具体实现类(这里是制作巧克力蛋糕和香草蛋糕类)

    java 复制代码
    // 具体巧克力蛋糕类
    public class ChocolateCake extends CakeBakingTemplate {
        @Override
        protected void prepareIngredients() {
            System.out.println("准备巧克力原料。");
        }
    
        @Override
        protected void bake() {
            System.out.println("在350度的温度下烘焙巧克力蛋糕30分钟。");
        }
    
        @Override
        protected void decorate() {
            System.out.println("用巧克力甘纳许装饰巧克力蛋糕。");
        }
    }
    java 复制代码
    // 香草蛋糕类
    public class VanillaCake extends CakeBakingTemplate {
        @Override
        protected void prepareIngredients() {
            System.out.println("准备香草配料。");
        }
    
        @Override
        protected void bake() {
            System.out.println("香草蛋糕在350度烘焙25分钟。");
        }
    
        @Override
        protected void decorate() {
            System.out.println("用香草糖霜装饰香草蛋糕。");
        }
    }

至此,我们就通过"生搬硬套"模板方法模式的模板设计出一套制作蛋糕的模板,接下来我们进行测试:

  • 测试代码

    java 复制代码
    public class Client {
        public static void main(String[] args) {
            CakeBakingTemplate chocolateCake = new ChocolateCake();
            chocolateCake.bakeCake();
    
            CakeBakingTemplate vanillaCake = new VanillaCake();
            vanillaCake.bakeCake();
        }
    }
  • 结果

    java 复制代码
    准备巧克力原料。
    在碗里混合配料。
    在350度的温度下烘焙巧克力蛋糕30分钟。
    用巧克力甘纳许装饰巧克力蛋糕。
    准备香草配料。
    在碗里混合配料。
    香草蛋糕在350度烘焙25分钟。
    用香草糖霜装饰香草蛋糕。

总结

模板方法模式实际上封装了一个固定流程,该流程由几个步骤组成,具体步骤可以由子类进行不同的实现,从而让固定的流程产生不同的结果。它非常简单,其实就是类的继承机制,但它却是一个应用非常广泛的模式。模板方法模式的本质是抽象封装流程,具体进行实现。

相关推荐
糖拌西红柿多放醋10 天前
SpringBoot利用InitializingBean实现策略模式
java·spring boot·spring·策略模式·模板方法模式
努力找工作的OMArmy22 天前
软件开发----设计模式每日刷题(转载于牛客)
java·单例模式·设计模式·策略模式·访问者模式·模板方法模式·开闭原则
麦克·唐1 个月前
模板方法模式、策略模式(C++)
c++·策略模式·模板方法模式
拉里小猪的迷弟1 个月前
设计模式-行为型-常用-1:观察者模式、模板模式、策略模式
观察者模式·设计模式·策略模式·模板方法模式
qq_366086221 个月前
Spring Boot与模板方法模式:实现统一的日志处理流程
java·spring boot·模板方法模式
神的孩子都在歌唱1 个月前
行为设计模式 -模板方法模式- JAVA
java·设计模式·模板方法模式
学步_技术1 个月前
Python编码系列—Python模板方法模式:定义算法骨架,让子类实现细节
python·算法·模板方法模式
java_heartLake1 个月前
设计模式之模板方法模式
java·设计模式·模板方法模式
愿天垂怜1 个月前
【C++】模板进阶
c语言·开发语言·c++·leetcode·stl·模板方法模式·string