设计模式之模板方法模式

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

优点

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

缺点

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

适用场景:

  • 多个子类有共同的方法,并且逻辑基本相同:通过模板方法将这些共同的方法提取到父类中,避免重复代码。
  • 需要控制子类的扩展:模板方法定义了算法的框架,子类只需实现特定的细节,而框架本身不变。
相关推荐
0白露32 分钟前
Apifox Helper 与 Swagger3 区别
开发语言
Tanecious.1 小时前
机器视觉--python基础语法
开发语言·python
叠叠乐2 小时前
rust Send Sync 以及对象安全和对象不安全
开发语言·安全·rust
战族狼魂2 小时前
CSGO 皮肤交易平台后端 (Spring Boot) 代码结构与示例
java·spring boot·后端
Tttian6223 小时前
Python办公自动化(3)对Excel的操作
开发语言·python·excel
xyliiiiiL3 小时前
ZGC初步了解
java·jvm·算法
杉之3 小时前
常见前端GET请求以及对应的Spring后端接收接口写法
java·前端·后端·spring·vue
hycccccch4 小时前
Canal+RabbitMQ实现MySQL数据增量同步
java·数据库·后端·rabbitmq
独好紫罗兰4 小时前
洛谷题单2-P5713 【深基3.例5】洛谷团队系统-python-流程图重构
开发语言·python·算法
天天向上杰5 小时前
面基JavaEE银行金融业务逻辑层处理金融数据类型BigDecimal
java·bigdecimal