设计模式之模板方法模式

一、什么是模板方法模式

模板方法模式,定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变算法结构的情况下重定义该算法的某些特定步骤。

模板方法模式,是一种行为型设计模式。

二、模板方法模式类图

设计模式之模板方法模式插图

三、模板方法模式角色

  • 抽象模板角色(AbstractTemplate): 抽象模板类,负责给出一个算法的轮廓和骨架。它由一个模板方法和若干个基本方法构成。

1、模板方法:定义了算法的骨架,按某种顺序调用其包含的基本方法。

2、基本方法:是整个算法中的一个步骤,包含以下几种类型:

1)抽象方法:在抽象类中声明,有具体子类实现。
2)具体方法:在抽象类中已经实现,在具体子类中可以继承或重写它。
3)钩子方法:在抽象类中已经实现,包括用于判断的逻辑方法和需要子类重写的空方法两种。

  • 具体模板角色(ConcreteTemplate): 继承抽象模板类,实现抽象类中的抽象方法和钩子方法。

四、模板方法模式优缺点

优点:

  1. 封装了不变部分,扩展可变部分。
  2. 在父类中提取了公共的部分代码,便于代码复用。
  3. 部分方法是由子类实现的,因此子类可以通过扩展方式增加相应的功能,符合开闭原则。

缺点:

  1. 对每个不同的实现都需要定义一个类,这会导致类的个数增加,系统更加庞大,设计也更加抽象,间接地增加系统实现的复杂度。
  2. 父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致一种反向的控制结构,它提高了代码阅读的难度。
  3. 由于继承关系自身的缺点,如果父类添加新的抽象方法,则所有子类都要修改。

五、模板方法模式demo示例

1、Demo需求

使用模板方法模式完成泡茶(红茶/绿茶),分为三步:第一步烧开水;第二步选择茶叶,并将茶叶放入茶壶中;第三步将开水倒入茶壶中,盖上盖子静待指定时间即可饮用。

2、抽象类定义

/**
  * @Description: 抽象模板类:沏茶
  **/ public abstract class AbstractTeaTemplate {
     /**
      * 烧水
      */     public void boilWater() {
         System.out.println("第一步:烧开水...");
     }
 
     /**
      * 选择茶叶,并放入茶壶
      */     public abstract void chooseTea();
 
     /**
      * 加入开水,泡制指定时间后即可
      */     public abstract void joinBoiledWater();
 
     public void makeTea() {
         // 1.烧开水
         boilWater();
         // 2.选择茶叶,并将茶叶放入茶壶
         chooseTea();
         // 3.将开水导入茶壶,并放置静泡指定时间后即可饮用
         joinBoiledWater();
     }
 }

3、具体化对象类

/**
  * 具体模板类:泡制红茶
  */ public class RedTeaTemplate extends AbstractTeaTemplate {
     @Override
     public void chooseTea() {
         System.out.println("第二步:选择红茶,并将红茶放入茶壶中...");
     }
 
     @Override
     public void joinBoiledWater() {
         System.out.println("第三步:将开水倒入茶壶,并泡制10分后即可饮用");
     }
 }
/**
  * 具体模板类:泡制绿茶
  */ public class GreenTeaTemplate extends AbstractTeaTemplate {
     @Override
     public void chooseTea() {
         System.out.println("第二步:选择绿茶,并将绿茶放入茶壶中...");
     }
 
     @Override
     public void joinBoiledWater() {
         System.out.println("第三步:将开水倒入茶壶,并泡制20分后即可饮用");
     }
 }

4、测试

/**
  * 模板方法模式客户端测试类
  */ public class Client {
     public static void main(String[] args) {
         // 1.泡制绿茶
         AbstractTeaTemplate greenTea = new GreenTeaTemplate();
         greenTea.makeTea();
         System.out.println("=======================");
 
         // 2.泡制红茶
         AbstractTeaTemplate redTea = new RedTeaTemplate();
         redTea.makeTea();
     }
 }
第一步:烧开水...
第二步:选择绿茶,并将绿茶放入茶壶中...
第三步:将开水倒入茶壶,并泡制20分后即可饮用
=======================
第一步:烧开水...
第二步:选择红茶,并将红茶放入茶壶中...
第三步:将开水倒入茶壶,并泡制10分后即可饮用

发表评论