深入解析Java的设计模式编程中的模板方法模式

 更新时间:2016年02月03日 17:41:47   作者:Zhang_H  
这篇文章主要介绍了深入解析Java的设计模式编程中的模板方法模式, 模版方法模式由一个抽象类和一个(或一组)实现类通过继承结构组成,需要的朋友可以参考下

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

听起来好高端的样子,我的理解:

    1.父类声明了若干个抽象方法(基本方法)和若干个具体方法(模板方法)

    2.抽象方法是一个算法(过程)的步骤,在子类中实现

    3.模板方法是一个算法(过程)的框架,在父类中已经约定好,实现对基本方法调用,完成固定的逻辑

    4.一个算法(过程)的结构在父类中定义,具体的实现细节则在子类中实现

    注:为了防止恶意操作,一般模板方法都加上final,禁止重写

通用类图:

201623173930405.jpg (381×239)

事实上,模版方法是编程中一个经常用到的模式。先来看一个例子,某日,程序员A拿到一个任务:给定一个整数数组,把数组中的数由小到大排序,然后把排序之后的结果打印出来。经过分析之后,这个任务大体上可分为两部分,排序和打印,打印功能好实现,排序就有点麻烦了。但是A有办法,先把打印功能完成,排序功能另找人做。

abstract class AbstractSort { 
   
  /** 
   * 将数组array由小到大排序 
   * @param array 
   */ 
  protected abstract void sort(int[] array); 
   
  public void showSortResult(int[] array){ 
    this.sort(array); 
    System.out.print("排序结果:"); 
    for (int i = 0; i < array.length; i++){ 
      System.out.printf("%3s", array[i]); 
    } 
  } 
} 

        写完后,A找到刚毕业入职不久的同事B说:有个任务,主要逻辑我已经写好了,你把剩下的逻辑实现一下吧。于是把AbstractSort类给B,让B写实现。B拿过来一看,太简单了,10分钟搞定,代码如下:

class ConcreteSort extends AbstractSort { 
 
  @Override 
  protected void sort(int[] array){ 
    for(int i=0; i<array.length-1; i++){ 
      selectSort(array, i); 
    } 
  } 
   
  private void selectSort(int[] array, int index) { 
    int MinValue = 32767; // 最小值变量 
    int indexMin = 0; // 最小值索引变量 
    int Temp; // 暂存变量 
    for (int i = index; i < array.length; i++) { 
      if (array[i] < MinValue){ // 找到最小值 
        MinValue = array[i]; // 储存最小值 
        indexMin = i;  
      } 
    } 
    Temp = array[index]; // 交换两数值 
    array[index] = array[indexMin]; 
    array[indexMin] = Temp; 
  } 
} 

写好后交给A,A拿来一运行:

public class Client { 
  public static int[] a = { 10, 32, 1, 9, 5, 7, 12, 0, 4, 3 }; // 预设数据数组 
  public static void main(String[] args){ 
    AbstractSort s = new ConcreteSort(); 
    s.showSortResult(a); 
  } 
} 

运行结果:

排序结果: 0 1 3 4 5 7 9 10 12 32

  
 
模版方法模式的结构
       模版方法模式由一个抽象类和一个(或一组)实现类通过继承结构组成,抽象类中的方法分为三种:
抽象方法:父类中只声明但不加以实现,而是定义好规范,然后由它的子类去实现。
模版方法:由抽象类声明并加以实现。一般来说,模版方法调用抽象方法来完成主要的逻辑功能,并且,模版方法大多会定义为final类型,指明主要的逻辑功能在子类中不能被重写。
钩子方法:由抽象类声明并加以实现。但是子类可以去扩展,子类可以通过扩展钩子方法来影响模版方法的逻辑。
抽象类的任务是搭建逻辑的框架,通常由经验丰富的人员编写,因为抽象类的好坏直接决定了程序是否稳定性。
       实现类用来实现细节。抽象类中的模版方法正是通过实现类扩展的方法来完成业务逻辑。只要实现类中的扩展方法通过了单元测试,在模版方法正确的前提下,整体功能一般不会出现大的错误。
 

 
模板方法模式的优点:

    1.  封装不变部分,扩展可变部分

    2.  提取公共部分代码,便于维护

    3.  行为由父类控制,子类实现

模板方法模式的适用场景:

    1.     多个子类有公共方法,并且逻辑基本相同

    2.    对复杂的算法,核心算法设计为模板方法,细节功能则由各个子类实现

    3.    重构代码

模板方法模式的扩展

  •     基本方法由于不需要对外提供访问,因此可以设计为protected类型
  •     设计钩子方法(Hook Method):对外部提供接口,可以影响模板方法内的具体执行顺序

总结:

    父类建立框架,子类在重写了父类部分方法后,再调用从父类继承的方法,产生不同的结果。

相关文章

  • Java中equals方法使用及重写练习

    Java中equals方法使用及重写练习

    equals是在object类中的方法,在object中equals是用来看看两个参数是否引用的是同一个对象,下面这篇文章主要给大家介绍了关于Java中equals方法使用及重写练习的相关资料,需要的朋友可以参考下
    2023-05-05
  • Mybatis-Plus3.x的创建步骤及使用教程

    Mybatis-Plus3.x的创建步骤及使用教程

    MyBatis-Plus是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为 简化开发、提高效率而生,这篇文章主要介绍了Mybatis-Plus3.x的使用,需要的朋友可以参考下
    2023-10-10
  • java求100之内的素数(质数)简单示例

    java求100之内的素数(质数)简单示例

    这篇文章主要介绍了java求100之内的素数简单示例,素数是一个大于1的自然数,如果除了1和它自身外,不能被其他自然数整除的数;否则称为合数
    2014-04-04
  • 对Java中JSON解析器的一些见解

    对Java中JSON解析器的一些见解

    这篇文章主要是对Java中JSON解析器的一些见解。需要的朋友可以过来参考下,希望对大家有所帮助
    2013-12-12
  • idea离线使用jrebel的超详细教程

    idea离线使用jrebel的超详细教程

    IDEA上原生是不支持热部署的,一般更新了 Java 文件后要手动重启 Tomcat 服务器,才能生效,下面通过本文给大家分享idea离线使用jrebel的超详细教程(亲测有效),感兴趣的朋友一起看看吧
    2020-12-12
  • Hibernate用ThreadLocal模式(线程局部变量模式)管理Session

    Hibernate用ThreadLocal模式(线程局部变量模式)管理Session

    今天小编就为大家分享一篇关于Hibernate用ThreadLocal模式(线程局部变量模式)管理Session,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-03-03
  • 详解Java拦截器以及自定义注解的使用

    详解Java拦截器以及自定义注解的使用

    这篇文章主要为大家介绍了Java拦截器以及自定义注解的使用,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助<BR>
    2021-12-12
  • 深入解析Java的Hibernate框架中的持久对象

    深入解析Java的Hibernate框架中的持久对象

    Hibernate的持久对象在数据库数据操作中有着重要作用,这里我们就来深入解析Java的Hibernate框架中的持久对象,首先必须从理解持久化对象的生命周期开始:
    2016-07-07
  • Java中Stream流的peek方法详解及常见使用场景

    Java中Stream流的peek方法详解及常见使用场景

    这篇文章主要介绍了Java中Stream流的peek方法详解及常见使用场景的相关资料,peek()方法是一个中间操作,用于在流的每个元素上执行一个操作,而不会改变流中的元素或中断流的处理,需要的朋友可以参考下
    2025-03-03
  • 详解java8在Collection中新增加的方法removeIf

    详解java8在Collection中新增加的方法removeIf

    这篇文章主要介绍了详解java8在Collection中新增加的方法removeIf的相关资料,需要的朋友可以参考下
    2018-01-01

最新评论