模板模式(Template Method Pattern)

定义一个算法的骨架,并允许子类为一个或者多个步骤提供实现。

模板方法使得子类可以在不改变算法结构的情况下,重新定义算法的某些步骤。

属于行为型设计模式。

适用场景:

1.一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。

2.各个子类中公共的行为被提取出来并且集中到一个公共的父类中,从而避免代码重复。

现实场景(坐飞机):

买票------进站安检-----找到飞机/临时有事,离开------飞行完成/原地返回

流程代码:

/*** @Author Darker* @Descrption 坐飞机的流程* @Date : Created in 9:41 2020-3-13*/
public abstract class TakeAPlane {//坐飞机的流程是固定的protected final void fly(){//买票this.buyTick();//安检this.SecurityCheck();//实现流程的微调,如果流程不用微调,可以不用if(isAnyThing()){//返回this.goBack();}else{//上飞机this.selectPlane();//飞行完成this.CompletionOfFlight();}}protected final void buyTick(){System.out.println("买票");}protected final void SecurityCheck(){System.out.println("安检");}//钩子方法protected boolean isAnyThing(){return false;}protected final void goBack(){System.out.println("临时有事,原路回家");}protected abstract void selectPlane();protected final void CompletionOfFlight(){System.out.println("一路平安,飞行完成");}
}/*** @Author Darker* @Descrption* @Date : Created in 10:07 2020-3-13*/
public class TakeAPlaneToHaiHang extends TakeAPlane{private boolean anyThing = false;public TakeAPlaneToHaiHang(boolean anyThing){this.anyThing = anyThing;}//留给子类的方法@Overrideprotected void selectPlane() {System.out.println("上了海航的飞机,海南航空空姐长得漂亮");}//重写钩子方法@Overrideprotected boolean isAnyThing() {return this.anyThing;}
}/*** @Author Darker* @Descrption* @Date : Created in 10:07 2020-3-13*/
public class TakeAPlaneToShanHang extends TakeAPlane{private boolean anyThing = false;public TakeAPlaneToShanHang(boolean anyThing){this.anyThing = anyThing;}//留给子类的方法@Overrideprotected void selectPlane() {System.out.println("上了山航的飞机,山东航空空姐身材好");}//重写钩子方法@Overrideprotected boolean isAnyThing() {return this.anyThing;}
}

测试代码:

/*** @Author Darker* @Descrption* @Date : Created in 10:13 2020-3-13*/
public class TakeAPlaneTest {public static void main(String[] args) {//坐海航TakeAPlane haiHang = new TakeAPlaneToHaiHang(false);haiHang.fly();System.out.println("-------------------------------------------------------");//坐山航,但临时有事情,老婆带着小姨子跑了TakeAPlane shanHang = new TakeAPlaneToShanHang(true);shanHang.fly();}
}

这个例子把一些公用的逻辑设定好了,子类只需要按事先预定好的流程走就可以了。

JDBC模板:

我们经常用一些数据层的框架,只需要传个sql和参数就会返回list,那现在我们来看看这个流程具体是怎么操作的。

/*** @Author Darker* @Descrption* @Date : Created in 10:57 2020-3-13*/
@Data
public class User {private String usename;private String password;private int age;private String addr;
}/*** @Author Darker* @Descrption 每行返回映射的处理方式接口* @Date : Created in 10:31 2020-3-13*/
public interface RowMapper<T> {T mapRow(ResultSet rs, int rowNum) throws Exception;
}/*** @Author Darker* @Descrption  jdbc模板* @Date : Created in 10:33 2020-3-13*/
public abstract class JdbcTemplate {private DataSource dataSource;public JdbcTemplate(DataSource dataSource){this.dataSource = dataSource;}public List<?> executeQuery(String sql,RowMapper<?> rowMapper,Object[] values){try {//1.获取连接Connection connection = this.getConnection();//2.创建语句集PreparedStatement preparedStatement =  this.createPrePareStatement(connection,sql);//3.执行语句集ResultSet resultSet = this.executeQuery(sql,preparedStatement,values);//4.处理结果集List<?> result = this.paresResultSet(resultSet,rowMapper);//5.关闭结果集this.closeResultSet(resultSet);//6.关闭语句集this.closeStatement(preparedStatement);//7.关闭连接this.closeConnection(connection);} catch (Exception e) {e.printStackTrace();}return null;}protected void closeConnection(Connection connection) throws Exception {connection.close();}protected  void closeStatement(PreparedStatement preparedStatement) throws Exception {preparedStatement.close();}protected  void closeResultSet(ResultSet resultSet) throws Exception {resultSet.close();}protected List<?> paresResultSet(ResultSet resultSet, RowMapper<?> rowMapper) throws Exception {List<Object> result = new ArrayList<>();int rowNum = 1;while(resultSet.next()){result.add(rowMapper.mapRow(resultSet,rowNum++));}return result;}protected  ResultSet executeQuery(String sql,PreparedStatement preparedStatement, Object[] values) throws Exception {for(int i=0,len =values.length;i<len;i++){preparedStatement.setObject(i,values);}return preparedStatement.executeQuery();}protected  PreparedStatement createPrePareStatement(Connection connection, String sql) throws SQLException {return connection.prepareStatement(sql);}public Connection getConnection() throws SQLException {return this.dataSource.getConnection();}
}/*** @Author Darker* @Descrption* @Date : Created in 10:58 2020-3-13*/
public class UserDao extends JdbcTemplate {public UserDao(DataSource dataSource){super(dataSource);}public List<?> selectAll(){String sql = "select * from t_user";return super.executeQuery(sql, new RowMapper<Object>() {@Overridepublic Object mapRow(ResultSet rs, int rowNum) throws Exception {User user = new User();//字段过多,可以用原型模式优化user.setUsename(rs.getString("username"));user.setPassword(rs.getString("password"));user.setAge(rs.getInt("age"));user.setAddr(rs.getString("addr"));return user;}},null);}}/*** @Author Darker* @Descrption* @Date : Created in 11:11 2020-3-13*/
public class UserDaoTest {public static void main(String[] args) {//有兴趣的小伙伴可以自己去测试一下,这里我就懒得去拿数据源了UserDao userDao = new UserDao(null);List<?> result = userDao.selectAll();System.out.println(result);}
}

源码中的应用 :

jdk源码中哪里使用了模板模式呢?

答案就是我们最长用的AbstractList了,我们找到它的get方法看看。

先看看子类对它抽象get方法的实现,看看是否有什么区别,第一个是ArrayList

它是先检查一下索引,然后提取元素,再看看ArrayQueue

显然,它要根据容量来取模,再来运算取值 ,但是他们有很多公共方法,这是很典型的模板模式。

再来看看我们每天都在用的HttpServlet。

它把大部分处理请求的逻辑都写好了,留了两个方法给子类实现,我们来看看它为什么能识别get,post方法。

跳到了它已经写好的公共逻辑里面了,对吧,这也是典型的模板模式。

继续,看看我们经常用的mybatis框架

它留了一些操作方法给我们,比如更新,查询等,它的子类实现也是不一样的,有兴趣的小伙伴也可以自己去看看。

总结:

优点:

1.提高了代码的复用性

2.提高了代码的扩展性

3.符合开闭原则

缺点:

1.类的数目增加

2.见解的增加了系统实现的复杂度

3.继承关系自身缺点,如果父类添加了新的抽象方法,所有子类都要改变

java设计模式————模板模式,手撸一个JDBCTemplate相关推荐

  1. Java设计模式-模板模式

    Java设计模式-模板模式 什么是模板模式? 模板模式,顾名思义,就是通过模板拓印的方式. 定义模板,就是定义框架.结构.原型.定义一个我们共同遵守的约定. 定义模板,我们的剩余工作就是对其进行充实. ...

  2. 【设计模式】Java设计模式 - 模板模式

    [设计模式]Java设计模式 - 模板模式

  3. Java设计模式—模板模式(Template)

    模板模式 业务需求 编写豆浆制作程序 选材-添加配料-浸泡-豆浆机打碎 选材.浸泡.打碎这几步对于制作不同豆浆都是一样的 比较简单,这里不再使用传统方法,直接上设计模式 模板模式基本介绍 模板模式,在 ...

  4. 手撸一个JdbcTemplate,带你了解其原理

    前提要求 能够使用jdbc链接数据库 能够利用jdbc完成数据库的增删改查等操作 对泛型有一定的了解 基本原理 通过jdbc链接数据库,查询数据库中内容 利用反射对数据库中查询字段进行封装 步骤 1. ...

  5. Java设计模式 - 模板模式

    目录 模板模式: 模板优点: 模板模式应用: 模板模式和策略模式区别: 模板实例: 上述代码 GitHub 地址:https://github.com/baicun/designPatterns 模板 ...

  6. Java 设计模式 --- Template 模式 Java Template 模式 Java 模板设计模式

    Java 设计模式 --- Template 模式 Java Template 模式 Java 模板设计模式 一.概述 模板设计模式: 父类定义通用抽象的功能方法,子类负责具体的实现. 本文将以一个通 ...

  7. 手撸一个动态数据源的Starter 完整编写一个Starter及融合项目的过程 保姆级教程

    手撸一个动态数据源的Starter! 文章目录 手撸一个动态数据源的Starter! 前言 一.准备工作 1,演示 2,项目目录结构 3,POM文件 二.思路 三.编写代码 1,定义核心注解 Ds 2 ...

  8. 五分钟,手撸一个Spring容器!

    Spring是我们最常用的开源框架,经过多年发展,Spring已经发展成枝繁叶茂的大树,让我们难以窥其全貌. 这节,我们回归Spring的本质,五分钟手撸一个Spring容器,揭开Spring神秘的面 ...

  9. Goroutine 并发调度模型深度解析之手撸一个高性能 goroutine 池

    文章目录 1 前言 2 Goroutine & Scheduler 2.1 线程那些事儿 2.1.1 用户级线程模型 2.1.2 内核级线程模型 2.1.3 两级线程模型 2.2 G-P-M ...

最新文章

  1. linux环境编程--IPC 之 msg queue
  2. 教你修改Linux下高并发socket最大连接数所受的各种限制
  3. C# 消息处理学习总结
  4. java普通类获取session_springboot普通类中如何获取session?
  5. 怎么往integer型数组添加数据_面试中经常问到的Redis七种数据类型,你都真正了解吗?...
  6. python文件编译_编译Python文件
  7. QT学习笔记(四):Qt5+MSVC编译 中文字符显示乱码问题解决
  8. 计算机语言低下限高上限,学习语言有没有上限
  9. C++控制台简单的用户登录
  10. RN性能优化以及事件监听
  11. 安全维护上最不应该犯的十个基本错误
  12. php 页面执行时长
  13. 又见回文数 NYOJ781
  14. 计算机网络第七版课后答案(谢希仁版)
  15. bat批量修改文件后缀名
  16. 信息安全意识分享—社会工程学
  17. 基于因果逻辑库的定性事件结果及结果方向性预测
  18. 橘子学ES11之URI搜索方式
  19. ubuntu禁用笔记本触摸板
  20. windows系统目录programdata和program file(x86)

热门文章

  1. 微信小程序获取WIFI列表可手动输入密码连接
  2. android WebView
  3. 三步跳过wegame登录
  4. 范数理解(0范数,1范数,2范数)
  5. 常用加密与解密算法示例代码
  6. 圆的css样式,圆形进度条css3样式
  7. java如何对不齐,java中的测不准原理_java认证
  8. python特征选择relieff图像特征优选_基于Relief特征选择算法的研究与应用
  9. vue.js bootstrap 下拉列表_Excel下拉菜单制作的小技巧
  10. MapGuide应用程序示例——你好,MapGuide!