设计模式之模板方法模式

1. 模板方法模式(Template Method)

模板方法模式 是带有模板功能的模式,组成模板的抽象方法被定义在父类中 ,父类只负责管理子类可以调用哪些方法,而抽象方法的具体实习由子类完成 ,在子类中决定具体的处理流程。也就是说,在不同的子类中实现不同的具体处理,但无论子类中具体如何实现,处理的流程都会按照父类中定义的那样进行

像这样在父类中定义处理流程的框架,在子类中实现具体处理的模式就称为Template Method模式

1.1. 模式架构

  • 抽象类(AbstractClass):抽象模板类 负责给出算法的轮廓和骨架 ,它由一个模板方法和若干个基本方法构成 。模板方法定义了整体的骨架,按某种顺序执行调用其包含的基本方法,基本方法的具体流程由具体子类实现
  • 具体类(ConcreteClass): 负责实现抽象类中定义的抽象方法 ,这些方法会在抽象类中被调用

1.2. 示例代码实现

场景:平常做饭时大致流程是有统一的模板的,具体的做饭流程一致,区别在于不同的菜有不同的处理工序,该业务就很适合使用模板方法模式。

抽象类(AbstractClass):

抽象模板类CookDiner

public abstract class CookDiner {
    public abstract void WashFoods();//交给子类去实现抽象方法WashFoods
    public abstract void CutFoods();//交给子类去实现抽象方法CutFoods
    public final void Cook(){//本抽象类中实现的Cook方法,确定执行骨架和流程
        WashFoods();
        CutFoods();
        //做饭
        System.out.println("开始做饭");
    }
}

具体类(ConcreteClass):

具体类Vegetables

public class Vegetables extends CookDiner {//Vegetables类是CookDiner类的子类
    private String vegetName;

    public Vegetables(String vegetName) {
        this.vegetName = vegetName;
    }

    @Override
    public void WashFoods() {//重写WashFoods方法,该方法会在Cook方法中被调用
        System.out.println("开始洗:" + vegetName);
    }

    @Override
    public void CutFoods() {//重写CutFoods方法,该方法会在Cook方法中被调用
        System.out.println("开始切:" + vegetName);
    }
}

具体类Meat

public class Meat extends CookDiner {//Meat类是CookDiner类的子类
    private String meatName;

    public Meat(String meatName) {
        this.meatName = meatName;
    }

    @Override
    public void WashFoods() {//重写WashFoods方法,该方法会在Cook方法中被调用
        System.out.println("开始洗:" + meatName);
    }

    @Override
    public void CutFoods() {//重写CutFoods方法,该方法会在Cook方法中被调用
        System.out.println("开始切:" + meatName);
    }
}

Main类:

public class Client {
    public static void main(String[] args) {
        //生成一个持有"黄瓜"的Vegetables类的实例
        CookDiner cookVeget = new Vegetables("黄瓜");
        //生成一个持有"牛肉"的Meat类的实例
        CookDiner cookMeat = new Meat("牛肉");

        //cookVeget、cookMeat都是CookDiner类的子类
        cookVeget.Cook();//可以调用继承的Cook方法
        cookMeat.Cook();//实际的程序行为取决于cookVeget类和cookMeat类的具体实现
    }
}

执行结果:

开始洗:黄瓜

开始切:黄瓜

开始做饭

开始洗:牛肉

开始切:牛肉

开始做饭

在以上示例代码中,抽象模板类 CookDiner定义了程序行为的框架和流程,父类通过Cook方法来按照流程处理方法,具体的方法由其子类Vegetables、Meat来实现。

与策略模式不同的是,模板方法模式会改变部分程序行为,而策略模式是用于替换整个算法

1.3. 优缺点

优点

  • 代码复用:公共代码抽取到模板方法中,避免重复实现。
  • **扩展性:**子类可以根据需要重写特定步骤,不影响算法整体结构。
  • **结构清晰:**算法框架清晰可见,易于理解和维护。

缺点

  • **固化框架:**有时过度使用模板方法可能会导致框架过于固定,不利于灵活应对变化。
  • **复杂度增加:**可能会增加系统的复杂度,特别是当算法步骤较多、逻辑复杂时。

适用场景:

  • 多个子类有共同的方法,并且逻辑基本相同:通过模板方法将这些共同的方法提取到父类中,避免重复代码。
  • 需要控制子类的扩展:模板方法定义了算法的框架,子类只需实现特定的细节,而框架本身不变。
相关推荐
qq_327342732 分钟前
Java实现离线身份证号码OCR识别
java·开发语言
锅包肉的九珍3 分钟前
Scala的Array数组
开发语言·后端·scala
心仪悦悦6 分钟前
Scala的Array(2)
开发语言·后端·scala
yqcoder29 分钟前
reactflow 中 useNodesState 模块作用
开发语言·前端·javascript
baivfhpwxf202339 分钟前
C# 5000 转16进制 字节(激光器串口通讯生成指定格式命令)
开发语言·c#
许嵩6642 分钟前
IC脚本之perl
开发语言·perl
长亭外的少年1 小时前
Kotlin 编译失败问题及解决方案:从守护进程到 Gradle 配置
android·开发语言·kotlin
直裾1 小时前
Scala全文单词统计
开发语言·c#·scala
心仪悦悦1 小时前
Scala中的集合复习(1)
开发语言·后端·scala
JIAY_WX1 小时前
kotlin
开发语言·kotlin