博客
关于我
软件设计模式修炼 -- 模板方法模式
阅读量:403 次
发布时间:2019-03-06

本文共 1895 字,大约阅读时间需要 6 分钟。

模板方法是结构最简单的行为型设计模式,在抽象类中定义了一个称为模板方法的方法,在这个方法中定义其他基本方法的执行步骤,而基本方法的实现可以放在抽象类,也可以放在其子类

模式动机

现实生活中很多事情的完成过程都包含几个基本步骤,例如请客吃饭,无论吃什么,一般都包含点单、吃东西、买单几个步骤,到底吃什么则具体情况具体分析,在实际环境中由用户动态决定。

既然这几个步骤的次序是固定的,于是我们创建一个新的方法叫“请客”,在其中调用了点单、吃东西和买单,同时指定它们的执行次序,我们称这个“请客”为模板方法,“点单”、“吃东西”、“买单”都是“请客”过程中的一个步骤,它们称为基本方法。其中“吃东西”可以有多种吃法,如吃饭、吃面条、吃烧烤,因此需要提供不同的“吃东西”方法的实现。

假设用代码实现上述方法,我们可以把相同代码放在父类,如“点单”和“买单”,而将不同方法实现放在不同的子类,如“吃东西”,这样一来提高了代码的复用性,还可以利用面向对象的多态性,这就是模板方法模式的模式动机。

模式定义

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

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 changing the algorithm’s structure.

模式分析

模板方法模式是基于继承的代码复用基本技术,先在抽象类的模板方法中指定执行步骤,将相同步骤对应的方法在抽象父类中实现,而不同的步骤只在抽象父类中进行声明。由于面向对象的多态性,子类中定义的方法将覆盖父类中定义的方法,因此程序运行时,具体子类的基本方法将覆盖父类中定义的基本方法,实现特定的算法。

不过,虽然说子类覆盖了父类的方法实现业务逻辑,但实际上是由父类来控制整个过程,即子类不需要调用父类,而通过父类来调用子类。

由此得模式结构类图如下:

抽象类(AbstractClass)中定义一系列基本操作(primitiveOperation),这些基本操作可以是具体的,也可以是抽象的,每一个基本操作对应算法的一个步骤,在其子类中可以重定义并实现一个算法的各个步骤。同时在抽象类中实现了一个模板方法(templateMethod),用于定义一个算法的骨架,调用基本操作。

具体子类(ConcreteClass)用于实现在父类中定义的抽象基本操作以完成子类特定算法的步骤,也可以覆盖在父类中实现的具体基本操作。

基本方法是实现各个步骤的方法,是模板方法的组成部分,基本方法又可以分为三种:

  • 抽象方法

    一个抽象方法由抽象类声明,由其具体子类实现

  • 具体方法

    一个具体方法由一个抽象类或具体类声明并实现,其子类可以进行覆盖

  • 钩子方法

    一个钩子方法由一个抽象类或具体类声明并实现,而其子类可能会加以扩展。通常在父类中给出的实现是一个空实现,作为该方法的默认实现,当然也可以提高一个非空的默认实现。

    钩子方法有两类,一类是可以控制具体步骤的执行,比如说我们希望在不同条件下执行模板方法中的不同步骤,就可以定义一个返回类型为布尔值的钩子方法,用于进行条件判断,如果条件满足则执行某一步骤,否则某一步骤不执行

    public void template() {    open();    display();    if(isPrint()) {        print();    }}public boolean isPrint(){    return true;}

    如果不希望方法执行,可以在其子类在覆盖钩子方法,修改返回值即可。

    还有一类钩子方法是实现体为空的具体方法,子类根据需要覆盖或继承它们,与抽象方法相比,钩子方法的好处在于如果没有覆盖父类中定义的抽象方法,编译仍可以通过。

模式优缺点

模板方法模式的优点:

  • 可以在一个类中形式化地定义算法,而由它的子类实现细节的处理
  • 模板方法模式是一种代码复用的基本技术,在类库设计中尤其重要,它提取类库中的公共行为,将公共行为放在父类,通过子类来实现不同的行为
  • 通过一个父类调用其子类的操作,通过对子类的扩展增加新的行为,符合开闭原则

模板方法模式的缺点:

  • 每个不同的实现都需要定义一个子类,将会导致类的个数增加

转载地址:http://ahjkz.baihongyu.com/

你可能感兴趣的文章
SpringCloud微服务(03):Hystrix组件,实现服务熔断
查看>>
网站故障公告1:使用阿里云RDS之后一个让人欲哭无泪的下午
查看>>
[网站公告]又拍云API故障造成图片无法上传(已恢复)
查看>>
上周热点回顾(6.9-6.15)
查看>>
.NET跨平台之旅:借助ASP.NET 5 Beta5的新特性显示CLR与操作系统信息
查看>>
上周热点回顾(7.27-8.2)
查看>>
上周热点回顾(5.9-5.15)
查看>>
上周热点回顾(1.23-1.29)
查看>>
云计算之路-阿里云上:14:20-14:55博客后台2台服务器都CPU 100%引发的故障
查看>>
【故障公告】10:30-10:45 左右 docker swarm 集群节点问题引发故障
查看>>
创建自己的Docker基础镜像
查看>>
Python 简明教程 --- 20,Python 类中的属性与方法
查看>>
看完你就明白的锁系列之锁的状态
查看>>
我的价值观
查看>>
QBlog V2.5 源码开放下载(ASP.NET 番外系列之开端)
查看>>
秋色园引发CPU百分百命案的事件分析与总结
查看>>
稀疏数组
查看>>
Android MediaPlayer setDataSource failed
查看>>
虚拟机搭建hadoop环境
查看>>
DataStax Bulk Loader教程(四)
查看>>