什么是模板模式?
- 大众理解:定义一个操作中算法的骨架,而将一些步骤延迟到子类中,模板方法使得子类可以不改变算法的结构即可重定义该算法的某些特定步骤。
- 民间理解( 个人):一套固定的流程,中间有一步或几步不确定的操作,需要根据特定的情况来给出特定的解决方案。即 完成一件事情,有固定的数个步骤,但是每个步骤根据对象的不同,而实现细节不同;就可以在父类中定义一个完成该事情的总方法,按照完成事件需要的步骤去调用其每个步骤的实现方法。每个步骤的具体实现,由子类完成。
模板模式的实现
案例一:旅行
旅行可分为固定的几个步骤:
1.选择游玩的地方
2.设计旅游攻略
3.选择交通工具
4.到达目的,开始游玩
其中1,2,4为固定步骤,3为非固定步骤,按照上面的模板模式的定义,这个场景就可以使用模板模式
旅行案例的UML
- TravelTemplate:抽象模板类,提供模板方法,把一些固定的步骤,抽取到抽象类中,子类根据自身的特点去实现非固定的步骤。
travel()为模板方法,这个方法中有四个步骤:
- selectTracelPlace() 选择游玩的地方
- designTravelTaiders() 设计旅游攻略
- selectTraffic() 选择交通方式
- arrivalsPlay() 到达目的,开始游玩
其中selectTraffic() 被两个子类所实现。
话不多说,上代码
package com.swh.design.template;
public abstract class TravelTemplate {
public void travel() {
// 1.选择游玩的地方
// 2.设计旅游攻略
// 3.选择交通工具
// 4.到达目的,开始游玩
selectTravelPlace();
designTravelRaiders();
selectTraffic();
arrivalsPlay();
}
private void arrivalsPlay() {
System.out.println("到达目的地,开始游玩");
}
protected abstract void selectTraffic();
private void designTravelRaiders() {
System.out.println("设计旅游攻略");
}
private void selectTravelPlace() {
System.out.println("选择游玩的地方");
}
}
package com.swh.design.template;
public class Train extends TravelTemplate {
@Override
protected void selectTraffic() {
System.out.println("使用火车去旅游");
}
}
package com.swh.design.template;
public class Plain extends TravelTemplate{
@Override
protected void selectTraffic() {
System.out.println("使用飞机到达目的地");
}
}
package com.swh.design.template;
public class TemplateClient {
public static void main(String[] args) {
new Plain().travel();
System.out.println("-------------------------");
new Train().travel();
}
}
运行结果:案列二 :JdbcTemplate
用过JDBC的通过应该都不会陌生,JDBC的几个步骤:
1.获取连接
2.准备sql
3.执行sql,并获取结果集
4.解析结果集
5.关闭连接
JdbcTemplate的UML
JdbcTemplate的模板中有固定的方法,其中handlerResult()方法是需要调用者自己根据自身的业务来特定处理的其他的都是固定流程。
代码
package com.swh.design.template.jdbc;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class JdbcTemplate {
private DataSource dataSource;
public JdbcTemplate(DataSource dataSource) {
this.dataSource = dataSource;
}
public List<Object> queryList(String sql,RowMapper rowMapper) throws Exception {
//1.获取连接
//2.准备sql
//3.执行sql,并获取结果集
//4.解析结果集
//5.关闭连接
Connection connection = getConnection();
PreparedStatement preparedStatement = getPreparedStatement(sql, connection);
ResultSet resultSet = getResultSet(preparedStatement);
List<Object> list = handlerResult(rowMapper, resultSet);
close(connection, preparedStatement);
return list;
}
private void close(Connection connection, PreparedStatement preparedStatement) throws SQLException {
preparedStatement.close();
connection.close();
}
private List<Object> handlerResult(RowMapper rowMapper, ResultSet resultSet) throws SQLException {
List<Object> list = new ArrayList<>();
if(resultSet.next()){
list.add(rowMapper.handlerResultInfo(resultSet));
}
return list;
}
private ResultSet getResultSet(PreparedStatement preparedStatement) throws SQLException {
return preparedStatement.executeQuery();
}
private PreparedStatement getPreparedStatement(String sql, Connection connection) throws SQLException {
return connection.prepareStatement(sql);
}
private Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
}
package com.swh.design.template.jdbc;
import java.sql.ResultSet;
public interface RowMapper {
Object handlerResultInfo(ResultSet resultSet);
}
package com.swh.design.template.jdbc;
public class User {
private String userId;
private String userName;
private String address;
private int age;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
package com.swh.design.template.jdbc;
import javax.sql.DataSource;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
public class UserDao {
private JdbcTemplate jdbcTemplate = new JdbcTemplate(null);
public List<Object> query(String sql){
try {
return jdbcTemplate.queryList(sql, new RowMapper() {
@Override
public Object handlerResultInfo(ResultSet resultSet) {
User user = new User();
try {
user.setUserId(resultSet.getString("userId"));
user.setAddress(resultSet.getString("address"));
user.setAge(resultSet.getInt("age"));
user.setUserName(resultSet.getString("userName"));
} catch (SQLException e) {
e.printStackTrace();
}
return user;
}
});
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
package com.swh.design.template.jdbc;
import java.util.List;
public class JdbcTemplateClient {
public static void main(String[] args) {
String sql = "select * from t_user";
List<Object> query = new UserDao().query(sql);
}
}