设计模式之模板方法模式

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. 优缺点

优点

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

缺点

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

适用场景:

  • 多个子类有共同的方法,并且逻辑基本相同:通过模板方法将这些共同的方法提取到父类中,避免重复代码。
  • 需要控制子类的扩展:模板方法定义了算法的框架,子类只需实现特定的细节,而框架本身不变。
相关推荐
捕鲸叉2 分钟前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer6 分钟前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法
Peter_chq8 分钟前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
Yaml431 分钟前
Spring Boot 与 Vue 共筑二手书籍交易卓越平台
java·spring boot·后端·mysql·spring·vue·二手书籍
小小小妮子~33 分钟前
Spring Boot详解:从入门到精通
java·spring boot·后端
hong16168835 分钟前
Spring Boot中实现多数据源连接和切换的方案
java·spring boot·后端
aloha_7891 小时前
从零记录搭建一个干净的mybatis环境
java·笔记·spring·spring cloud·maven·mybatis·springboot
记录成长java2 小时前
ServletContext,Cookie,HttpSession的使用
java·开发语言·servlet
前端青山2 小时前
Node.js-增强 API 安全性和性能优化
开发语言·前端·javascript·性能优化·前端框架·node.js
睡觉谁叫~~~2 小时前
一文解秘Rust如何与Java互操作
java·开发语言·后端·rust