博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
模板模式
阅读量:6084 次
发布时间:2019-06-20

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

hot3.png

最近在做批量合同生成业务,合同之间不同 ,每个合同均有一个模板。业务大致是数据准备(一致)、生成合同号(规则不同)、生成合同(模板不同)、上传合同(一致)。那么我们可以就根据这个业务来梳理一下模板模式。

模板模式实现示例

模板(方法)模式属于行为型模式,它定义一个操作中的算法的骨架,而将一些步骤推迟到子类当中实现。父类抽取并实现的是公共方法,对于可变方法,父类做的只是定义了可变行为的接口,具体实现留给子类去完成,实现对代码的重复利用。

  • 抽象类(AbstractClass):实现了模板方法,定义了算法的骨架
  • 具体类(ConcreteClass):实现抽象类中的抽象方法,用于完成完整的算法
public abstract class AbstractTemplate {    private String params;    public AbstractTemplate(String params){        this.params= params;    }    public void question(){        System.out.println("第一步,准备数据");        System.out.println("第二步,生成合同编码号");        generContractNo();        System.out.println("第三步,获取合同模板并批量生成合同");        //将params替换模板内参数,生成合同        getContractTemplate(params);        System.out.println("第四步,上传合同");    }    public abstract int generContractNo();    public abstract int getContractTemplate();}//合同A模板public class ContractATemplate extends AbstractTemplate{    @Override    public int generContractNo() {        return 111;    }    @Override    public int getContractTemplate(){        return 123;    }    public ContractATemplate(String params) {        super(params);    }}//合同B模板public class ContractBTemplate extends AbstractTemplate{    @Override    public int generContractNo() {        return 222;    }    @Override    public int getContractTemplate(){        return 456;    }    public ContractBTemplate(String params) {        super(params);    }}
@Testpublic void templatePatternTest(){    String params = "{id:'0001',name:'0001'}";    AbstractTemplate aTempate = new ContractATemplate(params);    AbstractTemplate bTempate = new ContractBTemplate(params);    aTempate.question();    bTempate.question();}

模板模式在spring中的运用

spring中的JdbcTemplate类就运用了模板方法,Java在执行数据库操作时的步骤无非如下几步:

1. 加载驱动
2. 建立连接
3. 获取Statement
4. 拼接参数(针对PreparedStatement)
5. 执行
6. 返回结果
7. 销毁连接

在这里只是简单,介绍一下,因此针对PreparedStatement,最大的可变之处就是5,6这个部分,因此JdbcTemplate将 1,2,3,4,7制作成模板(主要在execute*方法中),而对于5,6它通过匿名内部类的形式来实现(也就是说对于update、query等等 操作,都对5,6通过匿名内部类有不同的实现,匿名内部类实现的都是*callback接口,*callback都是额外定义的接口)

@Overridepublic 
T query(final String sql, final ResultSetExtractor
rse) throws DataAccessException { Assert.notNull(sql, "SQL must not be null"); Assert.notNull(rse, "ResultSetExtractor must not be null"); if (logger.isDebugEnabled()) { logger.debug("Executing SQL query [" + sql + "]"); } //匿名内部类 class QueryStatementCallback implements StatementCallback
, SqlProvider { @Override public T doInStatement(Statement stmt) throws SQLException { ResultSet rs = null; try { rs = stmt.executeQuery(sql); ResultSet rsToUse = rs; if (nativeJdbcExtractor != null) { rsToUse = nativeJdbcExtractor.getNativeResultSet(rs); } return rse.extractData(rsToUse); } finally { JdbcUtils.closeResultSet(rs); } } @Override public String getSql() { return sql; } } //真正执行的方法 return execute(new QueryStatementCallback());}

这里只贴出了其中一个query方法,其他的”套路”都跟它差不多,如果感兴趣的话自己可以深究一下JdbcTemplate源码

模板模式优缺点

优点:

  • 抽出不变行为,对代码的重复利用;要扩展的话,只需添加子类

缺点:

  • 按照我们的设计习惯,抽象类负责声明最抽象、最一般的事情属性和方法,实现类完成具体的事物属性和方法。但是模板方法模式却颠倒了,抽象类定义了 部分抽象方法,由子类实现,子类执行结果影响了父类的结果,也就是子类对父类产生了影响,这在复杂的项目中,会带来代码阅读的难度,而且也会让新手产生不适感
  • 因为引入了一个抽象类,如果具体实现过多的话,需要用户或开发人员需要花更多的时间去理清类之间的关系

转载于:https://my.oschina.net/xiaohai945/blog/1079072

你可能感兴趣的文章
Spring 开发环境搭建(二)
查看>>
客户关系管理系统中对客户及相关数据的导入导出分析处理
查看>>
Web 开发人员和设计师必读文章推荐【系列二十九】
查看>>
ios生成自签名证书,实现web下载安装app
查看>>
PHP Switch 语句
查看>>
可拖拽悬浮窗、对话框悬浮窗的简单实现
查看>>
各种Camera,总有一款适合你(二)
查看>>
ACID、Data Replication、CAP与BASE
查看>>
每日一句(2014-10-16)
查看>>
交换输出
查看>>
Android wakelock机制
查看>>
hdu3182 状态压缩水题
查看>>
SQL—— 事务
查看>>
Hibernate Annotation 设置字段的默认值
查看>>
你所不知道的SQL Server数据库启动过程,以及启动不起来的各种问题的分析及解决技巧...
查看>>
原已经安装好的nginx,现在需要添加一个未被编译安装的模块--echo-nginx-module-0.56...
查看>>
Android学习之适配器ArrayAdapter SimpleAdapter
查看>>
hdu 1561 The more, The Better (树上背包)
查看>>
SHELL函数处理
查看>>
一口气看完一个项目源码(一)之用户注册
查看>>