模板方法模式,来看这里的最香!

作者: 不正经的创作者 | 来源:发表于2020-05-12 17:22 被阅读0次

介绍

在面向对象开发过程中,通常会遇到这样的一个问题,我们知道一个算法所需的关键步骤,并确定了这些步骤的执行顺序,但是,某些步骤的具体实现是未知的,或者说某些步骤的实现是会随着环境的变化而改变的,例如,执行程序的流程大致如下:

  1. 检查代码的正确性;
  2. 链接相关的类库;
  3. 编译相关代码;
  4. 执行程序;

对于不同的程序设计语言,上述 4 个步骤都是不一样的,但是,它们的执行流程是固定的,这类问题的解决方案就是这们这篇的主要内容 - 模板方法模式。

定义

定义一个操作中算法的框架,将一些步骤交于子类具体实现,使得子类可以改变一个算法的结构即可重定义该算法的某些特定步骤。

使用场景

  1. 多个子类有公有的方法,并且逻辑基本相同时。
  2. 重要、复杂的算法,可以把核心算法设计为模板方法,周边的相关细节功能则由各个子类实现。
  3. 重构时,模板方法模式是一个经常使用的模式,把相同的代码抽取到父类中,然后通过钩子函数约束其行为。

UML 类图

  • AbsTemplate: 抽象类,定义了一套算法框架。
  • ConcreteImplA: 具体实现类 A。
  • ConcreteImpleB: 具体实现类 B。

代码示例

模板方法模式实际上是封装一个固定流程,就像是一套执行模板一样,第一步该做什么,第二步该做什么都已经在抽象类中定义好。而子类可以有不同的算法实现,在框架不被修改的情况下实现某些步骤的算法替换,下面就就以简单示例来说明一下。

简单示例

需求: 用代码简要描述开机过程

定义抽象的模板

  public abstract class AbstractComputer {

      /**
       * 开启电源
       */
      protected void powerOn(){
          System.out.println("开启电源");
      }

      /**
       * 硬件检查
       */
      protected void checkHardware(){
          System.out.println("硬件检查");
      }

      /**
       * 加载系统
       */
      protected void loadSystem(){
          System.out.println("加载系统");
      }

      /**
       * 屏幕显示
       */
      protected void showScreen(){
          System.out.println("屏幕显示");
      }

      /**
       * 输入用户信息
       */
      protected void login(){
          System.out.println("密码验证成功,进入主页面。");
      }

      /**
       * 启动计算机方法,步骤固定为开启电源、硬件检查、加载系统、屏幕显 
 示、登录。设计为 final 防止被重写
       */
      public final void startUp(){
          System.out.println("------>>>>>>>   startup  ");
          powerOn();
          checkHardware();
          loadSystem();
          showScreen();
          login();
          System.out.println("------>>>>>>>   Successful");
      }
  }

抽象模板实现 A

  public class CoderComputer extends AbstractComputer {

      @Override
      protected void login() {
          System.out.println("密码输入完成,交于系统检查。");
          super.login();
      }
  }

抽象模板实现 B

  public class MilitaryComputer extends AbstractComputer {

      @Override
      protected void checkHardware() {
          super.checkHardware();
          System.out.println("检查防火墙");
      }

      @Override
      protected void login() {
          System.out.println("视网膜扫描 \n 视网膜验证成功");
          super.login();
      }
  }

test

    @Test
    public void testTemplate(){

        AbstractComputer abstractComputerA = new CoderComputer();
        abstractComputerA.startUp();

        AbstractComputer abstractComputerB = new MilitaryComputer();
        abstractComputerB.startUp();
    }

output

   程序员电脑启动流程
  ------>>>>>>>   startup  
  开启电源
  硬件检查
  加载系统
  屏幕显示
  密码输入完成,交于系统检查。
  密码验证成功,进入主页面。
  ------>>>>>>>   Successful

  军用电脑启动流程
  ------>>>>>>>   startup  
  开启电源
  硬件检查
  检查防火墙
  加载系统
  屏幕显示
  视网膜扫描 
  视网膜验证成功
  密码验证成功,进入主页面。
  ------>>>>>>>   Successful

通过上面的模板例子可以看到 ,在 startUp 方法中有一些固定的执行顺序,但是,不同的场景执行实现的步骤各不相同,因此子类需要复写相应的方法来进行自定义处理,这里需要注意的是 startUp 为 final 方法,这样就可以保证模板的执行顺序不被外部更改,子类更改某一时刻执行的具体实现,这样就保证了整个逻辑流程的稳定性。

总结

模板方法模式用 4 个字概括就是:流程封装。也就是把某个固定的流程封装到一个 final 函数中,并让子类能够定制这个流程中的某些或者所有步骤,这就要求父类提取共用的代码,提升代码复用率,同时也带来了更好的可扩展性。

优点:

  1. 封装不变部分,扩展可变部分。
  2. 提取公共部分代码,便于维护。

缺点:

  1. 模板方法会带来代码阅读的难度,会让用户觉得难以理解。

相关文章

  • 模板方法模式,来看这里的最香!

    介绍 在面向对象开发过程中,通常会遇到这样的一个问题,我们知道一个算法所需的关键步骤,并确定了这些步骤的执行顺序,...

  • 模板方法模式

    学习路线 菜鸟教程模板方法模式模板方法模式(Template Method) - 最易懂的设计模式解析 总结 应用...

  • spring面试常见问题汇总

    Spring工作原理 1、spring原理 Spring里用的最经典的一个设计模式就是:模板方法模式。(这里我都不...

  • 11.8设计模式-模板模式-详解

    设计模式-模式模式 模板方法模式详解 模板方法模式在android中的实际运用 1.模板方法模式详解 2.模板方法...

  • 第5章 -行为型模式-模板方法模式

    一、模板方法模式的简介 二、模板方法模式的优点 三、模板方法模式的应用场景 四、模板方法模式的实例

  • Android设计模式系列(4)--SDK源码之模板方法模式

    模板方法,和单例模式是GOF的23中最简单的两种模式。 但是个人对模板方法的经典思想特别推崇,虽然模板方法在大对数...

  • 模板方法模式

    模板方法模式 模板方法模式的定义 模板方法模式(Template Method Pattern)是如此简单,以致让...

  • 设计模式系列-模板方法模式

    JAVA设计模式系列: 单例模式 观察者模式 模板方法模式 模板方法模式 定义 模板方法模式在一个方法中定义了算法...

  • 模板方法模式

    一、概念 二、模板方法模式UML图 三、模板方法模式的2个角色 四、模板方法与基本方法的概念 模板方法: 基本方法...

  • 设计模式 | 模板方法模式及典型应用

    本文的主要内容: 介绍模板方法模式 源码分析模板方法模式的典型应用Servlet 中的模板方法模式Mybatis ...

网友评论

    本文标题:模板方法模式,来看这里的最香!

    本文链接:https://www.haomeiwen.com/subject/tqqinhtx.html