1、概述

模板设计模式定义:定义一个操作中的算法骨架,将步骤延迟到子类中。

模板设计模式是一种行为设计模式,一般是准备一个抽象类,将部分逻辑以具体方法或者具体的构造函数实现,然后声明一些抽象方法,这样可以强制子类实现剩余的逻辑。不同的子类以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。这就是模板设计模式能达成的功能。

适用于一些复杂操作进行步骤分割、抽取公共部分由抽象父类实现、将不同的部分在父类中定义抽象实现、而将具体实现过程由子类完成。对于整体步骤很固定,但是某些部分易变,可以将易变的部分抽取出来,供子类实现。

角色:

抽象类:实现模板方法、定义算法骨架

具体类:实现抽象类中的抽象方法,完成特定的算法


2、代码示例

我们举一个比较常见的例子:将一个物品装进冰箱。为了达到这个目的我们一般有如下几步:

a:打开冰箱门

b:将物品装进冰箱

c:关上冰箱门

上面的这三步其实就是“将一个物品装进冰箱”这个算法的骨架。在这个算法中,物品这个字眼很重要,它是抽象的,而不是具体的,对于每个不同的物品,装入的时候行为可能不同,这一点非常重要。比如:

a:将一块猪肉放进冰箱--->一块猪肉这么小,直接放进去

b:将一头大象放进冰箱--->一头大象这么大,切碎放进去

上面只是不恰当的举个例子,只是为了说明:针对与不同物品,放入冰箱的动作(行为)不同。

特别注意:上面物品虽是抽象的,但是我最终想表达的是“将物品装进冰箱”这个行为是抽象的。

package com.yefengyu.pattern.template;

public abstract class AbstractClass
{
public final void execute()
{
open();
put();
close();
} private void open()
{
System.out.println("打开冰箱");
} private void close()
{
System.out.println("关闭冰箱");
} protected abstract void put();
}

上面的AbstractClass类中的execute方法就是一个算法骨架,它定义了复杂操作的许多步骤,其中需要注意:

(1)AbstractClass是抽象类,因为子类需要继承某些抽象方法

(2)execute是算法骨架,让外部调用,所以必须是public,但是又不想让子类进行重写,因此使用final关键字,如果重写则导致整个流程混乱。

(3)open和close方法是固定的步骤,定义为私有,不让子类修改。

(4)put方法是protected 的,保证子类可以重写,但是其它类无法看到,又是abstract 则子类必须重写。因为父类AbstractClass无法得知具体的物品该如何放入冰箱,只有靠子类去实现了。

下面来实现两个子类。

package com.yefengyu.pattern.template;

public class Pork extends AbstractClass
{
@Override
protected void put()
{
System.out.println("将一块猪肉装进冰箱:直接装啊");
}
}
package com.yefengyu.pattern.template;

public class Elephant extends AbstractClass
{
@Override
protected void put()
{
System.out.println("将大象装入冰箱:你必须剁碎再装入");
}
}

这两个子类虽然在put中都只打印了一句话,但是我们可以想象这里的操作十分复杂,并且流程大不一样。下面我们来实现客户端代码。

package com.yefengyu.pattern.template;

public class Client
{
public static void main(String[] args)
{
AbstractClass abstractClass = new Pork();
abstractClass.execute(); System.out.println("-------------------"); abstractClass = new Elephant();
abstractClass.execute();
}
}

运行结果如下

通过上面的例子,我么可以看出:不同的实现类,重写的抽象方法的逻辑不同,导致算法执行的结果也不相同,但是算法骨架是没有改变的。


3、案例剖析

大家应该使用Thread类,在学习的时候,一定都注意到这个问题,我们重写了run方法,但是线程启动的时候,为什么使用start方法?

package com.yefengyu.pattern.template;

public class MyThread
{
public static void main(String[] args)
{
Thread thread = new Thread(){
@Override
public void run()
{
System.out.println("###");
}
}; thread.start();
}
}

其实Thread类也使用了模板设计模式,只是有些地方有些差异。

    总结:

start方法就是算法骨架的入口,它定义算法的骨架;start0()方法是本地方法,该方法最终还是调用了Thread的run方法,具体细节不做介绍。那么我们可以简单的认为start0()就是run方法,那么这就和模板设计模式非常相似:

start方法:算法框架入口和骨架,和上面的AbstractClass的execute方法对应。

start0方法:可以看作run方法,虽然run方法不是抽象方法,但是也可以复写,并且一般必须复写,不然线程没啥业务,有啥意义呢?

Thread线程的使用start启动,做了很多其它的事情,也在某个地方调用了run方法,它是线程完整执行的入口,就和上面的AbstractClass的execute方法一样;如果线程调用run方法启动,只是和普通方法调用一样,无法真正启动一个线程。

java模板设计模式的更多相关文章

  1. Java中的模板设计模式,太实用了!

    顾名思义,模板设计模式就是将许多公用的常用的代码封装成一个模板,我们只需要实现不同的业务需求的代码,然后和模板组合在一起,那么就得到完整的逻辑. 在我们的日常开发中,常用的模板模式有两种实现方式:继承 ...

  2. JAVA设计模式:模板设计模式

    1.模板设计模式,是为了体现继承的作用.它主要的作用就是在类中定义一些公共的方法和标准,而其具体的实现则叫给其子类来根据子类具体的行为来实现:因为模板设计模式中必经还有一些自己的方法不是抽象的方法,只 ...

  3. Java 设计模式 ------ 模板设计模式

    模板设计模式主要来源于生活中有一些事情是有模板可以遵循的.举两个生活中的例子,如泡茶和泡咖啡,看一看. 泡茶有以下四个步骤:  1, 烧开水;  2 把茶放到水杯中; 3,倒入开水; 4, 加糖. 泡 ...

  4. Java设计模式——模板设计模式

    模板设计模式 1.模板模式简介 模板模式(Template ):模板方法模式是类的行为模式.准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑 ...

  5. Template Method 模板设计模式

    什么是模板设计模式 对于不了解的模板设计模式的来说,可以认为如同古代的造纸术一样,纸所以成型,取决于用了模板的形状,形状又由镂空的木板组成,而你想要造什么纸,又取决于你使用什么材料. 上面提到了两个关 ...

  6. Java的设计模式

    一.什么是设计模式: 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. ...

  7. java策略设计模式

    1.概述 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使他们可以相互替换,让算法独立于使用它的客户而独立变化. 其实不要被晦涩难懂的定义所迷惑,策略设计模式实际上就是定义一个接口,只要实现 ...

  8. java常用设计模式总览

    一.java的设计模式大体上分为三大类: 创建型模式(5种):工厂方法模式,抽象工厂模式,单例模式,建造者模式,原型模式. 结构型模式(7种):适配器模式,装饰器模式,代理模式,外观模式,桥接模式,组 ...

  9. 转 分享我在阿里工作十年接触过Java框架设计模式

    转 原文: 分享我在阿里工作十年接触过Java框架设计模式 一.前言 说起来设计模式,大家应该都耳熟能详,设计模式代表了软件设计的最佳实践,是经过不断总结提炼出来的代码设计经验的分类总结,这些模式或者 ...

随机推荐

  1. git 新建仓库

    rm -rf .git git init git add . git commit -m "Initial commit" git remote add origin <gi ...

  2. fopen特殊模式r+, w+, a+辨析

    fopen模式分两大类,即 TEXT模式:r, w, a, r+, w+, a+ BIN模式:rb, wb, ab, r+b, w+b, a+b 模式 读指针初始位置 写指针初始位置 模式用途 详细说 ...

  3. VS2017编译SNMP++步骤记录

    1.下载地址:https://www.agentpp.com/download.html 三个都下 2.新建解决方案 TestSnmp 3.下载后解压到解决方案文件夹(注意,解压后的 snmp++的版 ...

  4. StringUtils.isEmpty StringUtils.isBlank

    两个方法都是判断字符是否为空的.前者是要求没有任何字符,即str==null 或 str.length()==0:后者要求是空白字符,即无意义字符.其实isBlank判断的空字符是包括了isEmpty ...

  5. Windows+Apache+mod_wsgi+Flask部署方法

    环境:windows7 64bit 1.python版本3.6.5,32位 2.下载Apache,版本httpd-2.4.33-o102o-x86-vc14-r2,32位,vc14编译 3.下载mod ...

  6. 【笔记】Python基础五:装饰器

    一,什么是装饰器 本质就是函数,功能是为其他函数添加附加功能 原则: 1,不修改被修饰函数的源代码 2,不修改被修饰函数的调用方式 例子: import time def timmer(func): ...

  7. pycharm 配置svn

    1.找到本地svn.exe 2.配置svn路径 3.输入svn路径,然后会进行密码校验 问题 本地的TortoiseSVN在bin目录没有发现svn.exe 原因: 安装TortoiseSVN的时候 ...

  8. mysql表理解

    4.1 索引组织表 1.在innodb存储引擎中,每张表都有个主键,如果在创建表时没有显式地定义主键,则innodb存储引擎会按如下方式选择或创建主键: ①:首先判断表中是否有非空的唯一索引,如果有, ...

  9. “菜”鸟理解.NET Framework(CLI,CLS,CTS,CLR,FCL,BCL)

    既然要学.NET,就要先认识认识她,我不喜欢大段大段文字的东西,自己通过理解,画个图,来看看.NET的沉鱼落雁,闭月羞花之容. 最下层蓝色部分是.NET Framework的基础,也是所有应用软件的基 ...

  10. paloalto防火墙执行初始配置

    1.默认情况下,防火墙的 IP 地址为 192.168.1.1,用户名/密码为 admin/admin. 为了安全起见,在继续执行其他防火墙配置任务之前,必须更改这些设置.必须从 MGT 接口(即使计 ...