模板方法模式(模板方法设计模式)与回调机制解析

2023-10-26

模板方法是什么?

模板方法模式在一个方法中定义一个算法的骨架,将某些步骤推迟到子类中实现。模板方法模式可以让子类在不改变算法整体的结构情况下,重新定义算法中的某些步骤。

public  abstract class AbstractClass {
    public void templateMedhod(){
    	//一堆代码,通用的代码
        method1();
       //一堆代码,通用的代码
        method2();
       //一堆代码,通用的代码
        method3();
        
    }
    protected abstract void method3();

    protected abstract void method2();

    protected abstract void method1();
}
public class ConcreteClass1 extends AbstractClass {

    @Override
    protected void method3() {
        System.out.println("3");
    }

    @Override
    protected void method2() {
        System.out.println("2");
    }

    @Override
    protected void method1() {
        System.out.println("1");
    }
}
public class ConcreteClass2 extends AbstractClass {

    @Override
    protected void method3() {
        System.out.println("3");
    }

    @Override
    protected void method2() {
        System.out.println("2");
    }

    @Override
    protected void method1() {
        System.out.println("1");
    }
}
public class client {
    public static void main(String[] args) {
        AbstractClass tm = new ConcreteClass1();
        tm.templateMedhod();
    }
}

模式很简单,就是一个抽象类(AbstractClass ),定义方法。在具体实现类中进行实现。
具体实现类可以有一个,也可以有很多个。例如代码中的(ConcreteClass1,ConcreteClass2)

从代码中,我们就能看到,模板方法模式,复用和扩展。

我们可以将通用的代码,在templateMedhod 中书写。 对于每个模块的差异,分别进行实现。

回调机制

我们在开发过程中,常常也会用到回调机制。
回调机制有两种,一种是同步回调,一种是异步回调。

a调用b,b反过来调用a,就是回调。
在c中,可以用函数指针,java中需要使用回调函数的类对象。

代码示例:
例如张三给李四打电话:

定义一个回调接口

public interface ICallBack {
    void methodCallback();
}

张三

public class Zhangsan {

    public static void main(String[] args) {
        Zhangsan aClass = new Zhangsan();
        aClass.phoneCall();
    }

    public void phoneCall() {
        System.out.println("找到lisi");
        Lisi lisi = new Lisi();
        System.out.println("开始打电话");
        lisi.process(new ICallBack() {
            @Override
            public void methodCallback() {
                System.out.println("张三这也接通了");
            }
        });
    }


}

李四

public class Lisi {

	//用来处理电话
    public void process(ICallBack callBack){

        System.out.println("正在通话中。。。");
        System.out.println("等2s种后");
        try {
            Thread.sleep(1000*2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("lisi接电话了");
        callBack.methodCallback();

    }
}

运行结果是:

找到lisi
开始打电话
正在通话中。。。
等2s种后
lisi接电话了
张三这也接通了

同步回调指在函数返回之前执行回调函数;异步回调指的是在函数返回之后执行回调函数。
上面这种是同步回调函数。

框架举例JDBCTEMPLATE:

jdbc操作数据库很繁琐。有很多步骤。
//1.创建datasource
//2.获取connection
//3.创建statement
//4 执行sql语句
//5 处理resultset
//6 关闭资源对象

当我们使用jdbctemplate的时候,直接执行excute方法就行了。只需执行两个步骤就行了。

 //获取template实例
private JdbcTemplate jdbcTemplate=ioc.getBean(JdbcTemplate.class);
//执行sql语句
 String sql = "select * from Order";
 jdbcTemplate.execute(sql);

其他的重复步骤 封装到了框架中。

假设我们是设计者,那些重复的步骤封装。我们可以使用模板方法模式:
我们定义一个AbstractJdbcTemplate类

public abstract class AbstractJdbcTemplate{
 
    @Autowired
    private DataSource dataSource;
    
    public final Object execute(String sql) {  
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;
        try {
            connection = dataSource.getConnection();
            statement = connection.createStatement();
            resultSet = statement.executeQuery(sql);
            //处理结果使用模板方法
            Object object = handleResultSet(resultSet);         
            return object;
        } catch (SQLException e) {
            System.out.print(e);
        } finally {
            if (resultSet != null) {
                try {
                    resultSet.close();
                } catch (SQLException e) {
                }
            }
            if (statement != null) {
                try {
                    statement.close();
                } catch (SQLException e) {
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                }
            }
        }
        return null;
    }
    
    protected abstract Object handleResultSet(ResultSet rs) throws SQLException;  
}

handleResultSet用来处理 ResultSet
具体实现我们使用一个类来继承AbstractJdbcTemplate

public class OrderJdbcTemplate extends AbstractJdbcTemplate{
 
    @Override
    protected Object handleResultSet(ResultSet rs) throws SQLException {
 
        List<Order> orders = new ArrayList<Order>();
        while (rs.next()) {
            Order order = new Order(rs.getLong("id"), rs.getString("order_number"), rs.getString("delivery_address"));
            orders.add(order);
        }
        return orders;
    }
}

ResultSet 中的结果,并构建了业务对象进行返回。

我们再使用 OrderJdbcTemplate 执行目标 SQL 语句,如下代码所示

AbstractJdbcTemplate jdbcTemplate = new OrderJdbcTemplate();  
List<Order> orders = (List<Order>) jdbcTemplate.execute("select * from Order");

如果使用模板方法模式,我们在业务代码中需要定义各种实现类,我们需要创建和维护新类。

这也就是模板方法模式的弊端,使用了继承。我们知道写代码尽量使用接口而不是继承,也就是基于接口编程。

回调机制便是基于接口实现。

那么,我们将handleStatement 改为一个接口。

public interface StatementCallback {
    Object handleStatement(Statement statement) throws SQLException;  

}

那么原有的AbstractJdbcTemplate 需要修改如下:

public class CallbackJdbcTemplate {

 

    @Autowired

    private DataSource dataSource;

    

    public final Object execute(StatementCallback callback){  

        Connection connection = null;

        Statement statement = null;

        ResultSet resultSet = null;

        try {

            connection = dataSource.getConnection();

            statement = connection.createStatement();

            Object object = callback.handleStatement(statement);

            return object;

        } catch (SQLException e) {

            System.out.print(e);

        } finally {

            //省略异常处理

        }

        return null;

    }

}

上面的

 Object object = callback.handleStatement(statement);

使用了接口,这样把原来需要子类抽象的方法转嫁到了接口(StatementCallback )之上。
我们写代码的时候,就可以使用:

public Object queryOrder(final String sql)  {

 

        CallbackJdbcTemplate jdbcTemplate = new CallbackJdbcTemplate();

        return jdbcTemplate.execute(new StatementCallback() {
            public Object handleStatement(Statement statement) throws SQLException {
                ResultSet rs = statement.executeQuery(sql);
                List<Order> orders = new ArrayList<Order>();
                while (rs.next()) {
                    Order order = new Order(rs.getLong("id"), rs.getString("order_number"),
                            rs.getString("delivery_address"));

                    orders.add(order);
                }
                return orders;
            }
        });     
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

模板方法模式(模板方法设计模式)与回调机制解析 的相关文章

  • c++享元模式

    享元模式 1 享元模式简介 享元模式在 设计模式 可复用面向对象软件的基础 一书中是这样说的 运用共享技术有效地支持大量细粒度的对象 本质就是对大量细粒度的对象进行共享 不是每个对象都要通过new的方式去创建 而是通过区分对象的内部状态和外
  • 23种设计模式之装饰模式

    装饰模式 一个简陋的房子 它可以让人在里面居住 为人遮风避雨 但如果给它进行装修 那么它的居住环境就更加宜人了 程序中的对象也与房子十分类似 首先有一个相当于 房子 的对象 然后经过不断装饰 不断对其增加功能 它就变成了使用功能更加强大的对
  • python语法(高阶)-设计模式(单例模式)

    参考内容 黑马程序员
  • 行为型模式-策略模式

    package per mjn pattern strategy 抽象策略类 public interface Strategy void show package per mjn pattern strategy 具体策略类 用来封装算法
  • C++设计模式(二)观察者模式

    1 观察者模式知识点 1 定义 定义对象间的一种一对多的依赖关系 当一个对象的状态发生改变的时候 所有依赖它的对象都得到通知并自动更新 2 动机 将一个系统分割成一系列相互协作的类有一个常见的副作用 需要维护相关对象间的一致性 我们不希望为
  • 面向过程和面向对象的语言有哪些,以及优缺点(一篇文章让你理解)

    C语言是面向过程的 而C python java是面向对象的 面向过程的编程思想将一个功能分解为一 个一个小的步骤 我们通过完成一个一 个的小的步骤来完成一个程序 优点 这种编程方式 符合我们人类的思维 编写起来相对比较简单 缺点 但是这种
  • java需会(转载)

    一 基础篇 1 1 Java基础 面向对象的特征 继承 封装和多态 final finally finalize 的区别 Exception Error 运行时异常与一般异常有何异同 请写出5种常见到的runtime exception i
  • 设计模式--Abstract server模式 VS Adapter 模式

    适配器类似于现实世界里面的插头 通过适配器 我们可以将分属于不同类的两种不同类型的数据整合起来 而不必去根据某一需要增加或者修改类里面的方法 Adapter mode和Proxymode的区别 Proxy的关注点是职能转移 通过引入Prox
  • 设计模式-建造者模式

    文章目录 建造者模式 创建复杂对象的优雅方式 什么是建造者模式 建造者模式的使用场景 优缺点 示例 使用建造者模式创建电脑对象 建造者模式 创建复杂对象的优雅方式 在软件开发中 有时候我们需要创建具有复杂结构和多个组件的对象 直接在客户端代
  • 每日一问:你想如何破坏单例模式?

    前言 1 单例是什么 单例模式 是一种创建型设计模式 目的是保证全局一个类只有一个实例对象 分为懒汉式和饿汉式 所谓懒汉式 类似于懒加载 需要的时候才会触发初始化实例对象 而饿汉式正好相反 项目启动 类加载的时候 就会创建初始化单例对象 1
  • HeadFirst 设计模式学习笔记10——MVC分析

    1 M V C Model View Controller 模式 视图 控制器 这是一种范型 模型对象正是应用系统存在的理由 你设计的对象 包含了数据 逻辑和其他在你的应用领域创建定制的类 视图通常是控件 用来显示和编辑 控制器位于二者中间
  • java-IO流(5)-IO流中的设计模式(装饰器模式和适配器模式)的介绍

    目录 1装饰器模式 1 1定义 1 2代码实现 1 3装饰器特点 1 4装饰器在IO流中的使用 2配适器模式 2 1Adapter适配器 2 2代码实例 2 3适配器特点 2 4适配器优缺点 2 5适配器在IO中的使用 3装饰器与适配器异同
  • [C++]外观模式

    外观模式 Facade Pattern 隐藏系统的复杂性 并向客户端提供了一个客户端可以访问系统的接口 这种类型的设计模式属于结构型模式 它向现有的系统添加一个接口 来隐藏系统的复杂性 这种模式涉及到一个单一的类 该类提供了客户端请求的简化
  • [设计模式]模板方法模式(Template Method)

    1 意图 定义一个操作中的算法的骨架 而将一些步骤延迟到子类中 TemplateMethod使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤 2 动机 其实就是如意图所描述的 算法的骨架是一样的 就是有些特殊步骤不一样 就可以
  • 程序员必知的23种设计模式之组合模式

    文章目录 1 模式引出 学校院系展示需求 1 1 传统方案 1 2 传统方案问题分析 2 组合模式基本介绍 2 1 方案修改 3 组合模式解决的问题 4 组合模式的注意事项和细节 1 模式引出 学校院系展示需求 编写程序展示一个学校院系结构
  • 设计模式——State(状态)模式

    目录 前言 1 定义 2 适用性 3 结构 3 1 结构图 3 2 参与者 4 应用举例 4 1 State TcpState 4 2 Context TcpConnection 4 3 ConcreteState ListeningTcp
  • 哈工大2020软件构造Lab3实验报告

    本项目于4 21日实验课验收 更新完成 如果有所参考 请点点关注 点点赞GitHub Follow一下谢谢 2020春计算机学院 软件构造 课程Lab3实验报告 Software Construction 2020 Spring Lab 3
  • 泛型与反射机制在JDBC和Servlet编程中的实践

    写在前面 泛型与反射是java中的两种强大机制 可以很好的提高代码的灵活性和复用性 本篇文章向大家展现在JDBC和Servlet编程场景下反射和泛型技术的实践 通过灵活使用这两种机制打造 高度可复用的JDBC和Servlet代码 1 JDB
  • 自动化测试面试题(附答案)

    1 自动化代码中 用到了哪些设计模式 单例设计模式 工厂模式 PO设计模式 数据驱动模式 面向接口编程设计模式 2 什么是断言 Assert 断言Assert用于在代码中验证实际结果是不是符合预期结果 如果测试用例执行失败会抛出异常并提供断
  • 【设计模式之美】 SOLID 原则之五:依赖反转原则:将代码执行流程交给框架

    文章目录 一 控制反转 IOC 二 依赖注入 DI 三 依赖注入框架 DI Framework 四 依赖反转原则 DIP 一 控制反转 IOC 通过一个例子来看一下 什么是控制反转 public class UserServiceTest

随机推荐

  • Power bi 3.24 矩阵

    关注微信公共号 小程在线 关注CSDN博客 程志伟的博客 数据集链接见微信公共号底端 1 单击 可视化 窗格中的 矩阵 图标 在画布区域会出现矩阵的模板 由于没有填入数据 因此矩阵是灰色的 2 在 字段 窗格中勾选 类型 年份 实际产量 预
  • uni-app自定义组件不能使用v-for解决办法

    uni app自定义组件不能使用v for解决办法 原文 添加链接描述
  • matlab三维山峰/山脉/山地曲面数据图

    matlab三维山峰 山脉 山地曲面数据图 可以使用peaks函数 比如直接peaks 80 peaks 80 z 3 1 x 2 exp x 2 y 1 2 10 x 5 x 3 y 5 exp x 2 y 2 1 3 exp x 1 2
  • 前端使用Export2Excel将页面Table中的数据导出为Excel

    前端使用Export2Excel将页面Table中的数据导出为Excel 在项目中 用于需要将表格中的数据导出为Excel 根据用于自己的表头样式 经过千方百计的百度 终于找到了这个Export2Excel 插件 1 安装 需要以下几个插件
  • 7款超级好用的AI智能工具,功能超越你的想象

    分享7个好用的AI智能工具 都是日常能够经常用到的 有了它们可以大大提高工作学习效率 1 Notion AI AI写作 一个AI智能写作在线网站 只需要输入关键词就能快速生成一篇文章 可以大大提高办公学习效率 使用邮箱注册登录之后 在右侧点
  • 中input宽度_使用HOG对卫星图像中的船舶进行分类

    我在浏览Kaggle数据集时发现了这个有趣的机器学习数据集 https www kaggle com rhammell ships in satellite imagery 该机器学习数据集包括从卫星图像中提取的船舶图像以及一些负面实例 查
  • springboot中Controller层调用service层报错this.service is null

    报错信息 2022 10 18 09 11 35 661 ERROR GlobalExceptionHandler java 33 java lang NullPointerException Cannot invoke com yuhen
  • 自动化测试 - Appium + Python史上最全最简环境搭建步骤

    一 为什么是Appium 借一张图 1 1 Appium优点 l 开源 l 跨架构 NativeApp Hybird App Web App l 跨设备 Android iOS Firefox OS l 不依赖源码 l 使用任何WebDri
  • windows杀软在线识别平台

    前言 在内网攻防中 当拿到一个对外服务器权限后 必不可少的就是要上线MSF或者CS进行内网横移 这个时候如果服务器上存在杀软 就会影响木马上线 几款推荐的杀软在线识别平台 1 https www ddosi org av 1 php 2 h
  • postman 设置请求编码_在postman脚本中进行urlencode编码

    进行urlencode编码 在进行接口测试的过程中 一部分接口的参数需要做urlencode编码 如果将传输的参数直接编码进行发送 就无法灵活的修改参数了 也不能灵活使用环境变量 于是想在postman的Pre request Script
  • 【华为OD统一考试B卷

    在线OJ 已购买本专栏用户 请私信博主开通账号 在线刷题 运行出现 Runtime Error 0Aborted 请忽略 华为OD统一考试A卷 B卷 新题库说明 2023年5月份 华为官方已经将的 2022 0223Q 1 2 3 4 统一
  • APP压力测试之Monkey

    文章目录 前言 第一章 概述 1 1 什么是Monkey测试 1 2 Monkey测试的内容是什么 1 3 为什么要进行monkey测试 1 4 Monkey测试的有点是什么 有什么缺点 第二章 环境的搭建 2 1 Android SDK
  • Angular路由 ng-route和ui-router的区别

    什么是路由 路由是AngularJS构建单页面应用的基础 路由 就是网络数据或者请求进行分发的一个网络组件 路由就是一个用于请求URL分发和跳转的一个应用组件 Angular中通过 routeProvider路由服务提供者进行核心的配置处理
  • 软件打包成rpm包的方法

    01 所用软件 打包rpm建议使用fpm软件 fpm软件来源自ruby的生态 安装方式如下 首先安装ruby的环境 yum install ruby devel gcc make rpm build rubygems 再安装fpm软件 ge
  • 常用的国内 PyPI 镜像

    从网上整理一些常用的国内 PyPI 镜像 阿里云 https mirrors aliyun com pypi simple 清华 https pypi tuna tsinghua edu cn simple 中国科技大学 https pyp
  • 个人笔记新解-Obsidian

    欢迎关注 攻城狮Gala 公 众 号 每天一起学习 努力成为Web3全栈 自己之前一直在使用为知笔记 体验越来越糟糕 主要有几个原因 为知笔记的编辑器很难用 尤其是对md的支持很差 最近有备份需求 但是为知笔记新版本竟然去掉导出文件夹功能
  • 安装 Realtek HD Audio Driver 失败 Error Code : 0xE0000100

    更新声卡驱动提示 安装Realtek HD Audio Driver失败 Error Code 0xE0000100 错误 尝试各种版本驱动无效 以下是解决方案 1 下载windows7声卡驱动修复压缩包 直接复制以下下载地址下载 http
  • 我是女生,想进入IT行业难吗?

    女生进入IT职业真的不难 我从事IT职业6年多 身边有许多女同事 她们工资都非常高 她们中有程序员 测验人员 有技能支持人员 有产品司理 有项目司理 有UI规划师等等 她们有的是计算机专业结业的 也有非计算机专业结业的 虽然她们起点的确不太
  • fatal: Not a valid object name: ‘master‘.

    Git创建分支错误 Administrator DESKTOP RL96PC3 MINGW64 e dd master git branch devfatal Not a valid object name master 原因 是因为我们刚
  • 模板方法模式(模板方法设计模式)与回调机制解析

    模板方法是什么 模板方法模式在一个方法中定义一个算法的骨架 将某些步骤推迟到子类中实现 模板方法模式可以让子类在不改变算法整体的结构情况下 重新定义算法中的某些步骤 public abstract class AbstractClass p