18. 23种经典设计模式-32-模板方法模式

1. 模板方法模式(Tmeplate Method Pattern)

Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without chaging the algorithm’s structure. (定义一个操作算法的框架, 而将一些步骤延迟到子类实现, 使得子类不可改变算法的结构,只可重新定义具体的步骤)

1.1 核心思想

1.2 模板方法模式-类图

模板方法类图比较简单,只有两个角色

  • AbastractClass: 抽象类. 负责定义模板方法和具体步骤方法:
    • 模板方法: 可定义多个, 通常使用final 修饰符修饰, 防止子类篡改算法
    • 步骤方法: 通常定义为抽象方法, 由子类实现. 通常使用protected 修饰, 只允许子类访问.(需要注意,java语言中使用protected修饰时,同包下的其它类也能方法)
    • 钩子方法: 提供了缺省的实现,子类可以选择扩展. 钩子方法通常是一个空实现.

1.3 模板方法模式-优缺点

  • 优点: 封装不可变部分, 扩展可变部分, 代码重用性高.
  • 缺点: 父类抽象了操作流程, 而子类实现具体的操作步骤. 代码可读性差

1.4 模板方法模式-适用场景

  • 重要,复杂的算法. 可以将核心算法设计为模板方法
  • 多个子类拥有相类似的操作步骤, 有同的流程. 如发送http请求等
  • 重构时, 模板模式是一个经常使用的模式.

2. 模板方法模式-应用示例

我们来假定一种汽车软装场景,组装汽车需要三个步骤,安装天窗,安装全息影像,安装音响,这是固定流程。但是不同的品牌音响可以选择安装.

2.1 类图

2.2 模板抽象类

抽象模板类,定义模板方法和步骤方法:

  • constructCar: 模板方法,使用final 修饰, 防止子类篡改
  • buile*: 步骤方法, 定义为抽象方法,交给子类实现.
  • isBuildHologram: 钩子方法, 由子类决定是否需要安装全息影像.
public abstract class AbsCarProducer {

    // 组装标配车型
    public final void constructCar(){
        System.out.println("第1步:");
        this.buildSunroof();

        System.out.println("第2步:");
        this.buildHologram();

        System.out.println("第3步:");
        this.buildSound();

    }

    // 安装全景天窗
    protected abstract void buildSunroof();

    // 安装全息影像
    protected abstract void buildHologram();

    // 安装音响
    protected abstract void buildSound();
    
    // 是否安装全息影像,默认安装
    boolean isBuildHologram(){
        return true;
    }
}

2.3 奔驰实现类-BenzProducer

  • 实现各步骤方法
  • 不重写钩子方法,默认安装全息影像
public class BenzProducer extends AbsCarProducer {
    @Override
    void buildSunroof() {
        System.out.println("\t奔驰汽车-开始安装音响");
    }

    @Override
    void buildHologram() {
        System.out.println("\t奔驰汽车-开始安装天窗");
    }

    @Override
    void buildSound() {
        System.out.println("\t奔驰汽车-开始安装音响");
    }
}

2.4 奔驰实现类-BMWProducer

  • 实现各步骤方法
  • 重写钩子方法,不安装全息影像

public class BMWProducer extends AbsCarProducer {
    @Override
    void buildSunroof() {
        System.out.println("\t宝马汽车-开始安装音响");
    }

    @Override
    void buildHologram() {
        System.out.println("\t宝马汽车-开始安装天窗");
    }

    @Override
    void buildSound() {
        System.out.println("\t宝马汽车-开始安装音响");
    }

}

2.3 测试类

抽象类对外只暴露了constructCar()方法, 并不运行调用其具体的步骤方法.

    @Test
    public void test_benz(){
        AbsCarProducer benzProducer = new BenzProducer();
        benzProducer.constructCar();

        System.out.println("\n********************************\n");
        AbsCarProducer bmwProducer = new BMWProducer();
        bmwProducer.constructCar();
    }

2.4 测试输出

  • 奔驰汽车,按照模板方法,进行了三步组装
  • 宝马汽车,按照模板方法,只进行了两步组装
第1步:
	奔驰汽车-开始安装音响
第2步:
	奔驰汽车-开始安装天窗
第3步:
	奔驰汽车-开始安装音响

********************************

第1步:
	宝马汽车-开始安装音响
第3步:
	宝马汽车-开始安装音响

发布了321 篇原创文章 · 获赞 676 · 访问量 147万+

猜你喜欢

转载自blog.csdn.net/zongf0504/article/details/100103522
18.
今日推荐