源码中的设计模式–模板方法模式

本文要解决的几个问题,

1、什么是模板方法模式;

2、模板方法模式的使用场景;

3、模板方法模式的优点;

4、源码中有哪些地方使用到了模板方法模式;

带着这几个问题,我们开始今天的设计模式的分享。

一、模式入场

大家在日常的工作生活中肯定碰到过这样的场景,比如,你要转正答辩了,总要有个PPT吧,这时你是不是会问你同事要个述职的PPT模板,有个模板的好处这里自不用说。你去帮助单位去投标拿项目了,你是不是要问甲方爸爸要个模板,按照模板准备你的材料。生活中这样的例子太多了,有模板好办事。

在平时的开发过程中,不知道你是否碰到过类似的情形,你要调用系统A和系统B的接口,把系统A和系统B的数据读取过来,经过处理存储到自己的数据库里。

针对这样的场景你要怎么设计呐,首先,针对这样一个场景进行分析,要明确的是需要调用两个系统的接口,这两个系统返回的数据是不一样的,并且要存储到不同的表中,下面先试图实现下这个场景。有两个类SyncSystemA和SyncSystemB分别表示处理系统A和系统B的接口数据,

SyncSystemA.java

package com.example.template;

public class SyncSystemA {
    public void syncData(){
        //1、组装参数
        String url="http://a.com/query";
        String param="A";
        //2、发送请求
        String result=sendRequest(url,param);
        //3、解析
        String result2=parse(result);
        //4、保存数据
        saveData(result2);
    }
    private String sendRequest(String url,String param){
        System.out.println("发送请求到A");
        return "";
    }
    private String parse(String result){
        System.out.println("对A返回结果进行解析");
        return "";
    }
    private void saveData(String result){
        System.out.println("保存A的数据");
    }
}

SyncSystemB.java

package com.example.template;

public class SyncSystemB {
    public void syncData(){
        //1、组装参数
        String url="http://b.com/query";
        String param="A";
        //2、发送请求
        String result=sendRequest(url,param);
        //3、解析
        String result2=parse(result);
        //4、保存数据
        saveData(result2);

    }
    private String sendRequest(String url,String param){
        System.out.println("发送请求到B");
        return "";
    }
    private String parse(String result){
        System.out.println("对B的返回结果进行解析");
        return "";
    }
    private void saveData(String result){
        System.out.println("保存B的数据");
    }
}

下面看测试方法,Test.java

package com.example.template;

public class Test {
    public static void main(String[] args) {
        SyncSystemA syncSystemA=new SyncSystemA();
        SyncSystemB syncSystemB=new SyncSystemB();
        syncSystemA.syncData();
        System.out.println("-----------");
        syncSystemB.syncData();
    }
}

返回结果如下,

发送请求到A
对A返回结果进行解析
保存A的数据
组装发送到系统B的参数
发送请求
解析系统B的返回结果
保存数据

Process finished with exit code 0

看到上面的结果同样实现了功能,而且从代码风格上是不是更简洁,而且使用到了模板方法模式。

看下《Head First 设计模式》一书中给模板方法模式下的定义

模板方法模式在一个方法中 定义一个算法的骨架,而 将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下, 重新定义算法中的某些步骤

上面的释义定义的太完美了,多读几遍上面的释义和我们上面的AbstractSyncData类对比下

算法的骨架对应syncData方法

一些步骤延迟到子类对应assembleParam和parse方法

重新定义算法中的某些步骤对应assembleParam和parse方法,因为针对不同的实现有不同的处理逻辑。

模板方法的使用场景上面已经提到过, 在开发中要善于抽象,把一个场景中的步骤抽象成不同的几步,如果有多种实现,那么此时便是使用模板方法的大好时机。

番外

想多说一句的是,现在不是都谈面向接口编程,那么针对面向接口编程我们要如何改造上面的模板方法模式呐,只需要把syncData放到接口中即可,

package com.example.template;

public interface SyncData {
    //同步数据
    void syncData();
}

相应的抽象类实现该接口即可,

源码中的设计模式--模板方法模式

其UML图如下,

源码中的设计模式--模板方法模式

三、追寻源码

上面已经系统的学习了模板方法模式,下面看下在源码中的使用,

1、mybatis的BaseExecutor

在mybatis的BaseExecutor类中有update方法,

源码中的设计模式--模板方法模式

该方法来自于接口Executor,该方法又调用了doUpdate方法,该方法在BaseExecutor中是抽象方法,

源码中的设计模式--模板方法模式

看下实现的子类,

源码中的设计模式--模板方法模式

和我们上面的例子是不是很像,或者说就是同一个,再看下其uml

源码中的设计模式--模板方法模式

2、spring的AbstractApplicationContext

在spring的AbstractApplicaitonContext类中有fresh()方法,该方法中调用了obtainFreshBeanFactory方法,

源码中的设计模式--模板方法模式

obtainFreshBeanFactory方法,

源码中的设计模式--模板方法模式

看下这两个方法,

源码中的设计模式--模板方法模式

这两个方法是抽象的,肯定也是模板方法了。

四、总结

模板方法模式的精髓在于抽象,抽象出完成某个功能的步骤,再把个性化的步骤做为抽象方法,让子类延迟实现,公有的方法在抽象类中完成。在使用模板方法时由于存在抽象类,会出现多个继承子类的情况,需要视情况而定。另外,模板方法模式可以结合接口使用,实现面向接口编程。

源码中的设计模式--模板方法模式

首发于:https://www.toutiao.com/article/7097584508639183367/

Original: https://www.cnblogs.com/teach/p/16271356.html
Author: 良工说技术
Title: 源码中的设计模式–模板方法模式

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/594185/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Java的源码执行(建议结合Javase语法学习来加深印象)

    一、源码执行时的先后顺序: 父类的静态属性和静态块(按照声明顺序) 本类的静态属性和静态块(按照声明顺序) main方法 父类的成员属性和成员块(按照声明顺序) 父类构造器 本类成…

    Java 2023年6月5日
    091
  • 在 IDEA 里下个五子棋不过分吧?

    大家好,我是二哥呀!今天给大家分享一个基于Netty的IDEA即时聊天插件,可以实现即时聊天、游戏对战(下棋)。 GitHub 地址:https://github.com/anli…

    Java 2023年6月9日
    081
  • 一致性hash原理 看这一篇就够了

    ​ 在了解一致性哈希算法之前,最好先了解一下缓存中的一个应用场景,了解了这个应用场景之后,再来理解一致性哈希算法,就容易多了,也更能体现出一致性哈希算法的优点,那么,我们先来描述一…

    Java 2023年6月7日
    079
  • 工厂模式-理解Spring的Bean工厂(马士兵经典例子)

    工厂模式-理解Spring的Bean工厂 接面向对象里面 “老张开车去东北”的场景。链接名称 封装”老张开车去东北”里面的交通工具,…

    Java 2023年5月30日
    087
  • CSS 网页字体最佳实践

    一般在网页的字体设置中,可以将字体分类三类: 系统字体:使用系统自带的字体 兜底字体:当系统字体无法正常使用,而兜底的字体 Emoji 字体:显示网页中的表情字体 为了满足不同平台…

    Java 2023年6月8日
    083
  • 短信接口防盗刷解决方案

    在Web开发中,总有一些接口需要暴露在用户认证前访问,短信发送接口特别是短信验证码注册接口便是其中典型的一类,这类接口具有如下特点: 流量在用户认证之前 流量在用户认证之前,意味着…

    Java 2023年6月6日
    088
  • HTML常用标签

    HTML常用标签 DOCTYPE html> <html lang="en"> &lt…

    Java 2023年6月5日
    085
  • 分布式搜索引擎01

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    Java 2023年6月13日
    052
  • 正则表达式 匹配小括号中的内容 包括括号和不包括括号

    字符串举例: 床单(30%棉混纺布)勺子(40%铁)碗(99%陶) 期望值:30%棉混纺布 40%铁 99%陶 使用表达式: (\([^\)]*\)) &#x7ED3;&a…

    Java 2023年6月5日
    077
  • Error response from daemon: oci runtime error: container with id exists

    Error response from daemon: oci runtime error: container with id exists 序 常见问题之Docker——Err…

    Java 2023年6月5日
    056
  • Spring Cloud Consul 入门指引

    1 概述 服务发现——自动注册和注销服务实例的网络位置 健康检查——检测服务实例何时启动并运行 分布式配置——确保所有服务实例使用相同的配置 在本文中,我们将了解如何配置 Spri…

    Java 2023年6月7日
    090
  • IO流(Properties的使用方法)

    Properties:属性集合类。是一个可以和IO流相结合使用的集合类。 Properties 可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串。 /* 特殊功能…

    Java 2023年6月5日
    090
  • 基于css的一些动画

    最近因为期末复习周,博客更新鸽了很久,趁着考完试还记得这件事,把之前的大作业里出现过的css动画总结一下 这个图片原型是一个静态图 动画效果如下 .footer{ backgrou…

    Java 2023年6月8日
    079
  • 如何成为一名JAVAEE软件工程师?(前言)

    笔者将会整理出一整套成为一个JAVAEE工程师的学习路线和资料。欢迎同行和网友们订阅或指正。不定期更新。 笔者在软件工作做了7年java开发,开发过ERP,CRM等应用系统并担任过…

    Java 2023年6月9日
    073
  • Java 泛型程序设计

    1. 泛型类 public class Pair<t> { private T first; private T second; public void setSeco…

    Java 2023年6月16日
    082
  • 3、封装和继承

    隐藏细节 通过访问修饰符private,有些细节不需要用户直接访问,将他隐藏起来。只能间接访问,通过提供一些共有的接口(给外部提供一个可以调用的方法) 会写JavaBean fin…

    Java 2023年6月6日
    066
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球