设计模式之模板方法模式(template)
模板方法模式
规范执行流程
提高代码扩展性,复用性
符合开闭原则
案例
ORM框架
mapper接口
public interface RowMapper<T> {
T mapRow(ResultSet rs,int rowNum) throws Exception;
}
jdbcTemplate
public class JdbcTemplate {
private DataSource dataSource;
public JdbcTemplate(DataSource dataSource) {
this.dataSource = dataSource;
}
public List<?> executeQuery(String sql,RowMapper<?> rowMapper ,Object[] values){
try {
// 获取连接
Connection conn = this.getConnection();
// 创建语句集
PreparedStatement ps = this.createStatement(conn, sql);
// 执行语句集
ResultSet rs = this.executeQuery(ps, values);
// 处理结果集
List<?> result = this.parseResultSet(rs, rowMapper);
// 关闭结果集
this.closeResultSet(rs);
// 关闭语句集
this.closeStatement(ps);
// 关闭连接
this.closeConnection(conn);
return result;
}catch (Exception e){
e.printStackTrace();
}
return null;
}
public List<?> parseResultSet(ResultSet rs, RowMapper<?> rowMapper) throws Exception{
List<Object> result = new ArrayList<>();
int rowNum = 1;
while (rs.next()){
result.add(rowMapper.mapRow(rs,rowNum++));
}
return result;
}
public ResultSet executeQuery(PreparedStatement ps, Object[] values) throws Exception{
for(int i= 0;i<values.length;i++){
ps.setObject(i,values[i]);
}
return ps.executeQuery();
}
public PreparedStatement createStatement(Connection conn, String sql) throws Exception{
return conn.prepareStatement(sql);
}
public Connection getConnection() throws SQLException {
return this.dataSource.getConnection();
}
public void closeConnection(Connection conn) throws Exception{
conn.close();
}
public void closeStatement(PreparedStatement ps) throws Exception{
ps.close();
}
public void closeResultSet(ResultSet rs) throws Exception {
rs.close();
}
}
List<?> result = this.parseResultSet(rs, rowMapper);作为钩子函数
实体类
public class User {
private String username;
private String password;
// get/set ...
}
模板实现类
public class UserDao extends JdbcTemplate{
public UserDao(DataSource dataSource) {
super(dataSource);
}
public List<?> selectAll(String sql){
return super.executeQuery(sql, new RowMapper<User>() {
@Override
public User mapRow(ResultSet rs, int rowNum) throws Exception {
User user = new User();
user.setUsername(rs.getString("username"));
user.setPassword(rs.getString("password"));
return user;
}
},null);
}
}
Main
public class Main {
public static void main(String[] args) {
// 模拟调用
UserDao userDao = new UserDao(null);
List<?> users = userDao.selectAll("select * from user");
System.out.println(users);
}
}
暴露一个钩子函数可供后续实现类处理不同逻辑,但是主流程可控
应用
AbstractList get()作为钩子函数
HttpServlet service()作为钩子函数
设计模式之模板方法模式(template)
https://www.blaaair.com/archives/she-ji-mo-shi-zhi-mo-ban-fang-fa-mo-shi-template