【设计模式】第十三章:模板方法模式详解及应用案例

系列文章

【设计模式】七大设计原则
【设计模式】第一章:单例模式
【设计模式】第二章:工厂模式
【设计模式】第三章:建造者模式
【设计模式】第四章:原型模式
【设计模式】第五章:适配器模式
【设计模式】第六章:装饰器模式
【设计模式】第七章:代理模式
【设计模式】第八章:桥接模式
【设计模式】第九章:外观模式 / 门面模式
【设计模式】第十章:组合模式
【设计模式】第十一章:享元模式
【设计模式】第十二章:观察者模式
【设计模式】第十三章:模板方法模式
【设计模式】第十四章:策略模式
【设计模式】第十五章:责任链模式
【设计模式】第十六章:迭代器模式
【设计模式】第十七章:状态模式
【设计模式】第十八章:备忘录模式
【设计模式】第十九章:访问者模式
【设计模式】第二十章:解释器模式
【设计模式】第二十一章:命令模式
【设计模式】第二十二章:中介者模式



一、定义

摘自百度百科: 模板方法模式定义了一个算法的步骤,并允许子类别为一个或多个步骤提供其实践方式。让子类别在不改变算法架构的情况下,重新定义算法中的某些步骤。


二、角色分类

抽象类(Abstract Class)

定义了一系列的基本操作,这些具体操作可以是具体的,也可以是抽象的,每一个基本操作都对着算法的一个步骤,在其子类中可以重写或实现这些步骤。同时,在抽象类中实现了一个模板方法,用来定义一个算法的框架,模板方法不仅可以调用抽象类中实现的基本方法,可以调用抽象类的子类中实现的基本方法和其他对象中的方法

具体子类(Concrete Class)

它是抽象类的子类,用于实现在父类中声明的抽象操作,以完成子类特定算法的步骤,也可以覆盖在父类中已经实现的步骤

客户角色(Client)

具体调用方法的角色


三、实现方式

UML图

Image.png

具体实现

我们以入住酒店为例,我们先定义一个抽象类CheckIn,用它来定义我们入住的具体流程

抽象类角色(Abstract Class)

public abstract class CheckInHotel {

  protected final void CheckInProcess() {
    // 选择酒店
    this.chooseHotel();
    // 验证身份
    this.verifyIdentity();
    // 给钱
    this.pay();
    // 入住
    this.checkIn();
  }

  protected void verifyIdentity() {
    System.out.println("掏出身份证验证身份");
  }

  protected void checkIn() {
    System.out.println("入住酒店了");
  }

  protected abstract void chooseHotel();

  protected abstract void pay();
}

具体子类(Concrete Class)

public class FirstChoice extends CheckInHotel {

  @Override
  protected void chooseHotel() {
    System.out.println("选择酒店一");
  }
  
  @Override
  protected void pay() {
    System.out.println("使用支付宝支付");
  }
}

public class SecondChoice extends CheckInHotel {

  @Override
  protected void chooseHotel() {
    System.out.println("选择酒店二");
  }
  
  @Override
  protected void pay() {
    System.out.println("使用微信支付");
  }
}

客户角色(Client)

public class Client {
  public static void main(String[] main) {
    FirstChoice first = new new FirstChoice();
    first.checkInProcess();

    SecondChoice second = new new SecondChoice();
    second.checkInProcess();
  }
}

运行结果

选择酒店一
掏出身份证验证身份
使用支付宝支付
入住酒店了

选择酒店二
掏出身份证验证身份
使用微信支付
入住酒店了

四、应用场景

以下部分内容摘自菜鸟教程

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

主要解决: 一些方法通用,却在每一个子类都重新写了这一方法。

何时使用: 有一些通用的方法。

如何解决: 将这些通用算法抽象出来。

关键代码: 在抽象类实现,其他步骤在子类实现。

应用实例:

  1. 在造房子的时候,地基、走线、水管都一样,只有在建筑的后期才有加壁橱加栅栏等差异。
  2. 西游记里面菩萨定好的 81 难,这就是一个顶层的逻辑骨架。
  3. spring 中对 Hibernate 的支持,将一些已经定好的方法封装起来,比如开启事务、获取 Session、关闭 Session 等,程序员不重复写那些已经规范好的代码,直接丢一个实体就可以保存。

使用场景:

  1. 有多个子类共有的方法,且逻辑相同。
  2. 重要的、复杂的方法,可以考虑作为模板方法。

**注意事项:**为防止恶意操作,一般模板方法都加上 final 关键词。


五、优缺点

优点

  1. 封装不变部分,扩展可变部分。
  2. 提取公共代码,便于维护。
  3. 行为由父类控制,子类实现。

缺点

每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞大。


推荐

关注博客和公众号获取最新文章

Bummon’s BlogBummon’s Home公众号

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bummon.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值