专栏首页java程序员思维java设计模式之模板模式,站在巨人的肩膀上成功

java设计模式之模板模式,站在巨人的肩膀上成功

模板模式

模板模式(Template Pattern),定义一个操作中算法的骨架,而将一些步骤延迟到子类中,模板方法使得子类可以不改变算法的结构,只是重定义该算法的某些特定步骤。这种类型的设计模式属于行为型模式。

模板模式解决的问题

一些方法通用,却在每一个子类都重新写了这一方法,带来大量重复的代码的问题。相同的部分父类给出统一的模板,不同的部分,子类进行重写。

命令模式模式角色

AbstractTemplate(抽象类):在抽象类中定义了一系列基本操作,这些基本操作可以是具体的,也可以是抽象的,每一个基本操作对应算法的一个步骤,在其子类中可以重定义或实现这些步骤。同时,在抽象类中实现了一个模板方法(Template Method),用于定义一个算法的框架,模板方法不仅可以调用在抽象类中实现的基本方法,也可以调用在抽象类的子类中实现的基本方法,还可以调用其他对象中的方法。

ConcreteTemplate(具体子类):它是抽象类的子类,用于实现在父类中声明的抽象基本操作以完成子类特定算法的步骤,也可以覆盖在父类中已经实现的具体基本操作。

模板抽象类方法类型

抽象方法:在抽象类声明、由其具体子类实现。

具体方法:在抽象类中声明并实现,在具体子类中可以继承或重写。

钩子方法:在抽象类中声明并实现(可以是空的实现),子类视情况进行重写覆盖,一般是逻辑判断方法。

模板方法:定义统一模板算法的方法,提供实现方法,子类一般不需要重写。

模板模式和策略模式的区别

模板模式定义了一个统一的算法,子类可以对算法的某一些步骤,进行覆盖重写,可以提高代码的复用率。同过继承的方式实现,依赖比较强,不够灵活。策略模式每个子类都是一种实现,可以完全不相同,即便算法之间存在共性,也需要在每个子类重新实现,通过聚合的方式实现,可以动态的改变算法,比较灵活。

代码实现

/**
 * 抽象模板
 */
public abstract class Game {
 /**
 * 具体方法
 */
 public void initialize(){
 System.out.println("game initialize .........");
 }
 /**
 * 抽象方法
 */
 abstract void startPlay();
 abstract void endPlay();
 /**
 * 钩子方法
 * @return 是否需要结束
 */
 boolean isNeedEnd(){
 return false;
 }
 /**
 * 模板方法
 * final修饰 不允许子类修改
 * 每一个游戏先初始化、开始游戏 是否需要结束游戏 根据钩子进行判断
 */
 public final void play(){
 //初始化游戏
 initialize();
 //开始游戏
 startPlay();
 if(isNeedEnd()){
 //结束游戏
 endPlay();
 }
 }
}
/**
 * 具体模板
 * 足球游戏
 */
public class Football extends Game{
 @Override
 void endPlay() {
 System.out.println("Football Game Finished!");
 }
 @Override
 void startPlay() {
 System.out.println("Football Game Started. Enjoy the game!");
 }
 @Override
 boolean isNeedEnd() {
 return false;
 }
}
/**
 * 模板测试类
 */
public class TemplateModeTest {
 public static void main(String[] args) {
 Game game = new Basketball();
 game.play();
 game = new Football();
 game.play();
 }
}

运行结果:

JDK和框架中的模板模式

public <T> T execute(StatementCallback<T> action) throws DataAccessException {
 Assert.notNull(action, "Callback object must not be null");
 Connection con = DataSourceUtils.getConnection(getDataSource());
 Statement stmt = null;
 try {
 Connection conToUse = con;
 if (this.nativeJdbcExtractor != null &&
 this.nativeJdbcExtractor.isNativeConnectionNecessaryForNativeStatements()) {
 conToUse = this.nativeJdbcExtractor.getNativeConnection(con);
 }
 stmt = conToUse.createStatement();
 applyStatementSettings(stmt);
 Statement stmtToUse = stmt;
 if (this.nativeJdbcExtractor != null) {
 stmtToUse = this.nativeJdbcExtractor.getNativeStatement(stmt);
 }
 T result = action.doInStatement(stmtToUse);
 handleWarnings(stmt);
 return result;
 }
 catch (SQLException ex) {
 // Release Connection early, to avoid potential connection pool deadlock
 // in the case when the exception translator hasn't been initialized yet.
 JdbcUtils.closeStatement(stmt);
 stmt = null;
 DataSourceUtils.releaseConnection(con, getDataSource());
 con = null;
 throw getExceptionTranslator().translate("StatementCallback", getSql(action), ex);
 }
 finally {
 JdbcUtils.closeStatement(stmt);
 DataSourceUtils.releaseConnection(con, getDataSource());
 }
}
public boolean isSkipResultsProcessing() {
 return this.skipResultsProcessing;
}

spring中的JdbcTemplate、RedisTemplate、RestTemplate都是典型的模板模式,都是继承Accessor类和实现Operations接口。

优缺点

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

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

生活中的命令模式

PPT模板,从网上下载自己喜欢的PPT模板,在不改变大的整体框架的情况下,替换掉部分内容,比如文字内容、部分图片内容,可以很大程度提高产出率。

机器学习中的迁移学习,也是一个典型的模板模式,机器学习中提供了很多模板模型,VGG19、ResNet50、InceptionV3,如果我们自己训练这个模型需要花很长的时间,几周或者更长的时间,可以把别人训练好的模型作为模板,做一些细微的调整,去训练我们自己的样本数据,得到一个适合我们特有数据的模型,只需要训练比较短的时间,就能得到一个比较好的模型。

我的启发

模板模式就像站在巨人的肩膀上,在大方向上借鉴别人的经验,进行适当的调整,以满足我们自己定制化的需求。当我们不具备造轮子的能力的时候,合理选择适合的模板也是一种不错的选择。

设计模式系列文章历史

java设计模式之适配器模式,大丈夫能屈能伸

Head First 设计模式之命令模式,各司其职提高效率

Head First 设计模式之装饰器模式,因为参与,所以认同

Head First 设计模式之单例模式,每个人都是唯一

Head First 设计模式之观察者模式,你我都是发布者和订阅者

Head first 设计模式之策略模式,来源于生活,用之于生活

本文分享自微信公众号 - java程序员思维(java_python_go),作者:曾建路

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-05-04

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • java设计模式之状态模式,策略模式的孪生兄弟

    状态模式(State Pattern)中,类的行为是基于它的状态改变的,状态之间的切换,在状态A执行完毕后自己控制状态指向状态B,状态模式是不停的切换状态执行,...

    用户4361942
  • java设计模式之组合模式

    组合(Composite Pattern)模式的定义:有时又叫作部分-整体模式,它是一种将对象组合成树状的层次结构的模式,用来表示“部分-整体”的关系,使用户对...

    用户4361942
  • java设计模式之访问者模式

    访问者(Visitor Pattern)模式的定义:将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元...

    用户4361942
  • 设计模式—— 十 :模板方法模式

    模板方法模式是结构最简单的行为型设计模式,在其结构中只存在父类与子类之间的继承关 系。通过使用模板方法模式,可以将一些复杂流程的实现步骤封装在一系列基本方法中,...

    三分恶
  • 使用FTP连接池封装工具类

    早前的思路是将FTP连接的管理(对象池功能)与FTP工具类(上传下载方法)在一个工程中实现,在工具类中调用是模板类提供的模板方法, 由模板方法与对象池打交道——...

    用户3579639
  • [Oracle ASM全解析] 管理磁盘组模板

    7-5 为冗余属性的值和磁盘组冗余级别的对应关系,有MIRROR,HIGH,UNPROTECTED三种

    bsbforever
  • django-4-模板标签,模板继承

    {% if %}{% elif %}{% else %}{% endif %} 判断

    py3study
  • Go 视图模板篇(一):模板引擎的定义、解析与执行

    在 Web 编程中,模板引擎用于聚合数据和模板并生成最终的 HTML 文档,处理器调用模板引擎来完成这一工作并将 HTML 文档作为响应实体发送给客户端:

    学院君
  • 前端页面热更新实现方案

    腾讯NEXT学位
  • 设计模式03——Template Method模式

    模板方法(Template Method)模式就是带有模板功能的模式 ,组成模板方法的方法被定义在父类中,这些方法是抽象方法,在模板方法中规定了这些方法的执行流...

    itlemon

扫码关注云+社区

领取腾讯云代金券