资讯 小学 初中 高中 语言 会计职称 学历提升 法考 计算机考试 医护考试 建工考试 教育百科
栏目分类:
子分类:
返回
空麓网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
空麓网 > 计算机考试 > 软件开发 > 后端开发 > Java

设计模式-模板模式

Java 更新时间: 发布时间: 计算机考试归档 最新发布

设计模式-模板模式

模板模式


文章目录

  • 模板模式
  • 什么是模板模式
  • 为什么要用模板模式
  • 如何使用模板模式
  • 总结

什么是模板模式

  模板方法模式在一个方法中定义一个算法骨架,并将某些步骤推迟到子类中实现。模板方法模式可以让子类在不改变算法整体结构的情况下,重新定义算法中的某些步骤。这里的“算法”,我们可以理解为广义上的“业务逻辑”,并不特指数据结构和算法中的“算法”。这里的算法骨架就是“模板”,包含算法骨架的方法就是“模板方法”,这也是模板方法模式名字的由来。


为什么要用模板模式

  模板模式有两大作用:复用和扩展。其中,复用指的是,所有的子类可以复用父类中提供的模板方法的代码。扩展指的是,框架通过模板模式提供功能扩展点,让框架用户可以在不修改框架源码的情况下,基于扩展点定制化框架的功能。
  我们在【设计模式-观察者模式】一文中提到过,可以通过实现ApplicationListener来完成对Spring全局事件的监听,代码如下:

public class ZfDtpRunInfoCollectEventLocalFileListener implements ApplicationListener {	@Override    public final void onApplicationEvent(ZfDtpRunInfoCollectEvent event) {        ZfDtpCollectTimeInfo zfDtpCollectTimeInfo = (ZfDtpCollectTimeInfo) event.getSource();                // 获取采集信息        String collectDay = zfDtpCollectTimeInfo.getCollectDay();        // 保存线程池状态        String localFilePath = CommonUtil.getFilePath(this.getLocalFilePathPrefix(), collectDay);        ArrayList appendLines = new ArrayList<>();        appendLines.add(JSONUtil.toJsonStr(zfDtpCollectTimeInfo));        FileUtil.appendLines(appendLines, localFilePath, StandardCharsets.UTF_8);    }}

  可以看到上面的代码中,我们实现了ApplicationListener接口,而这个接口中的onApplicationEvent方法入参为你自己定义的一个事件,需要通过

ZfDtpCollectTimeInfo zfDtpCollectTimeInfo = (ZfDtpCollectTimeInfo) event.getSource();

  来获取具体的信息,那么这一段代码实际上是每一个监听器都应该实现的,此时我们就可以通过模板模式来完成代码复用,代码示例如下:

// 抽象模板类public abstract class ZfDtpAbstractRunInfoCollectEventListener implements ApplicationListener {    @Override    public final void onApplicationEvent(ZfDtpRunInfoCollectEvent event) {        ZfDtpCollectTimeInfo zfDtpCollectTimeInfo = (ZfDtpCollectTimeInfo) event.getSource();        doCollect(zfDtpCollectTimeInfo);    }    protected abstract void doCollect(ZfDtpCollectTimeInfo zfDtpCollectTimeInfo);}// 具体实现类public class ZfDtpRunInfoCollectEventLocalFileListener extends ZfDtpAbstractRunInfoCollectEventListener {    private ZfDtpProperties zfDtpProperties;    private String localFilePathPrefix;    @Override    public void doCollect(ZfDtpCollectTimeInfo zfDtpCollectTimeInfo) {        // 获取采集信息        String collectDay = zfDtpCollectTimeInfo.getCollectDay();        // 保存线程池状态        String localFilePath = CommonUtil.getFilePath(this.getLocalFilePathPrefix(), collectDay);        ArrayList appendLines = new ArrayList<>();        appendLines.add(JSONUtil.toJsonStr(zfDtpCollectTimeInfo));        FileUtil.appendLines(appendLines, localFilePath, StandardCharsets.UTF_8);    }}

  可以看到,我们优化后的代码是需要集成抽象类ZfDtpAbstractRunInfoCollectEventListener并重写doCollect方法保存我们采集的线程池信息即可。
  上面我们优化的代码其实同时兼备了模板模式的两个优点,一是代码复用,复用了将事件信息转换成我们需要的对象这一部分代码;二是易于拓展,只需要实现我们定义的抽象类,重写doCollect方法就能完成信息的保存。不需要考虑如何获取具体的事件与详细信息。


如何使用模板模式

  我们上面的代码中其实是一个非常简单的模板模式,定义一个抽象父类,将不需要子类复写的方法加上final,将需要子类实现的方法定义为抽象方法,我们用代码示例来看下:

// 抽象父类public abstract class AbstractTemplate {    public final void templateMethod(){        step1Method();        step2Method();        step3Method();    }    abstract void step1Method();    abstract void step2Method();    abstract void step3Method();}// 具象子类public class ChildClass extends AbstractTemplate{    @Override    void step1Method() {        // 具体实现步骤一    }    @Override    void step2Method() {        // 具体实现步骤二    }    @Override    void step3Method() {        // 具体实现步骤三    }}// 使用public class TestTemplate {    public static void main(String[] args) {        AbstractTemplate abstractTemplate = new ChildClass();        abstractTemplate.templateMethod();    }}

总结

  模板模式的用法和应用场景比较简单,我们在项目中应该比较常用,需要注意的是模板方法尽量使用final修饰避免子类重写导致模板失效。

转载请注明:文章转载自 http://www.konglu.com/
本文地址:http://www.konglu.com/it/1097328.html
免责声明:

我们致力于保护作者版权,注重分享,被刊用文章【设计模式-模板模式】因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理,本文部分文字与图片资源来自于网络,转载此文是出于传递更多信息之目的,若有来源标注错误或侵犯了您的合法权益,请立即通知我们,情况属实,我们会第一时间予以删除,并同时向您表示歉意,谢谢!

我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2023 成都空麓科技有限公司

ICP备案号:蜀ICP备2023000828号-2