java设计模式————模板模式,手撸一个JDBCTemplate
模板模式(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相关推荐
- Java设计模式-模板模式
Java设计模式-模板模式 什么是模板模式? 模板模式,顾名思义,就是通过模板拓印的方式. 定义模板,就是定义框架.结构.原型.定义一个我们共同遵守的约定. 定义模板,我们的剩余工作就是对其进行充实. ...
- 【设计模式】Java设计模式 - 模板模式
[设计模式]Java设计模式 - 模板模式
- Java设计模式—模板模式(Template)
模板模式 业务需求 编写豆浆制作程序 选材-添加配料-浸泡-豆浆机打碎 选材.浸泡.打碎这几步对于制作不同豆浆都是一样的 比较简单,这里不再使用传统方法,直接上设计模式 模板模式基本介绍 模板模式,在 ...
- 手撸一个JdbcTemplate,带你了解其原理
前提要求 能够使用jdbc链接数据库 能够利用jdbc完成数据库的增删改查等操作 对泛型有一定的了解 基本原理 通过jdbc链接数据库,查询数据库中内容 利用反射对数据库中查询字段进行封装 步骤 1. ...
- Java设计模式 - 模板模式
目录 模板模式: 模板优点: 模板模式应用: 模板模式和策略模式区别: 模板实例: 上述代码 GitHub 地址:https://github.com/baicun/designPatterns 模板 ...
- Java 设计模式 --- Template 模式 Java Template 模式 Java 模板设计模式
Java 设计模式 --- Template 模式 Java Template 模式 Java 模板设计模式 一.概述 模板设计模式: 父类定义通用抽象的功能方法,子类负责具体的实现. 本文将以一个通 ...
- 手撸一个动态数据源的Starter 完整编写一个Starter及融合项目的过程 保姆级教程
手撸一个动态数据源的Starter! 文章目录 手撸一个动态数据源的Starter! 前言 一.准备工作 1,演示 2,项目目录结构 3,POM文件 二.思路 三.编写代码 1,定义核心注解 Ds 2 ...
- 五分钟,手撸一个Spring容器!
Spring是我们最常用的开源框架,经过多年发展,Spring已经发展成枝繁叶茂的大树,让我们难以窥其全貌. 这节,我们回归Spring的本质,五分钟手撸一个Spring容器,揭开Spring神秘的面 ...
- Goroutine 并发调度模型深度解析之手撸一个高性能 goroutine 池
文章目录 1 前言 2 Goroutine & Scheduler 2.1 线程那些事儿 2.1.1 用户级线程模型 2.1.2 内核级线程模型 2.1.3 两级线程模型 2.2 G-P-M ...
最新文章
- linux环境编程--IPC 之 msg queue
- 教你修改Linux下高并发socket最大连接数所受的各种限制
- C# 消息处理学习总结
- java普通类获取session_springboot普通类中如何获取session?
- 怎么往integer型数组添加数据_面试中经常问到的Redis七种数据类型,你都真正了解吗?...
- python文件编译_编译Python文件
- QT学习笔记(四):Qt5+MSVC编译 中文字符显示乱码问题解决
- 计算机语言低下限高上限,学习语言有没有上限
- C++控制台简单的用户登录
- RN性能优化以及事件监听
- 安全维护上最不应该犯的十个基本错误
- php 页面执行时长
- 又见回文数 NYOJ781
- 计算机网络第七版课后答案(谢希仁版)
- bat批量修改文件后缀名
- 信息安全意识分享—社会工程学
- 基于因果逻辑库的定性事件结果及结果方向性预测
- 橘子学ES11之URI搜索方式
- ubuntu禁用笔记本触摸板
- windows系统目录programdata和program file(x86)