上面的代码中有个钩子方法可能有些小伙伴还不是太理解 , 在此我稍作解释。设计钩子方法的主要
目的是用来干预执行流程 , 使得我们控制行为流程更加灵活, 更符合实际业务的需求。 钩子方法的返回
值—般为适合条件分支语句的返回值 (如 boolean、 int等 )。小伙伴们可以根据自己的业务场景来决
定是否需要使用钩子方法。 接下来创建 JavaCourse 类:
public class JavaCourse extends AbastractCourse { private boolean needCheckHomework = false; public void setNeedCheckHomework(boolean needCheckHomework) { this.needCheckHomework = needCheckHomework; } @Override protected boolean needCheckHomework() { return this.needCheckHomework; } protected void checkHomework() { System.out.println("检查Java作业"); } }
创建 PythonCourse 类:
public class PythonCourse extends AbastractCourse { protected void checkHomework() { System.out.println("检查Python作业"); } }
客户端测试代码:
public class Test { public static void main(String[] args) { System.out.println("=========架构师课程========="); JavaCourse java = new JavaCourse(); java.setNeedCheckHomework(false); java.createCourse(); System.out.println("=========Python课程========="); PythonCourse python = new PythonCourse(); python.createCourse(); } }
通过这样一个案例, 相信下伙伴们对模板方法模式有了一个基本的印象。为了加深理解 , 下面我们
来结合—个室见的业务场景。
利用模板方法模式重构 JDBC 操作业务场景
创建—个模板类 JdbcTemplate , 封装所有的 JDBC 操作。以奎询为例, 每次奎询的表不同, 返回
的数据结构也就不一样。 我们针对不同的数据 , 都要封装成不同的实体对象。而每个实体封装的逻辐都
是不一样的 ,但封装前和封装后的处理流程是不变的 ,因此, 我们可以使用模板方法模式来设计这样的
业务场景。
先创建约束 ORM 逻韬的接口 RowMapper :
public interface RowMapper<T> { T mapRow(ResultSet rs,int rowNum) throws Exception; }
在创建封装了所有处理流程的抽象类 JdbcTemplate :
public abstract class JdbcTemplate { private DataSource dataSource; public JdbcTemplate(DataSource dataSource) { this.dataSource = dataSource; } public final List<?> executeQuery(String sql,RowMapper<?> rowMapper,Object[] values){ try { //1、获取连接 Connection conn = this.getConnection(); //2、创建语句集 PreparedStatement pstm = this.createPrepareStatement(conn,sql); //3、执行语句集 ResultSet rs = this.executeQuery(pstm,values); //4、处理结果集 List<?> result = this.parseResultSet(rs,rowMapper); //5、关闭结果集 rs.close(); //6、关闭语句集 pstm.close(); //7、关闭连接 conn.close(); return result; }catch (Exception e){ e.printStackTrace(); } return null; } private List<?> parseResultSet(ResultSet rs, RowMapper<?> rowMapper) throws Exception { List<Object> result = new ArrayList<Object>(); int rowNum = 0; while (rs.next()){ result.add(rowMapper.mapRow(rs,rowNum++)); } return result; } private ResultSet executeQuery(PreparedStatement pstm, Object[] values) throws SQLException { for (int i = 0; i < values.length; i++) { pstm.setObject(i,values[i]); } return pstm.executeQuery(); } private PreparedStatement createPrepareStatement(Connection conn, String sql) throws SQLException { return conn.prepareStatement(sql); } private Connection getConnection() throws SQLException { return this.dataSource.getConnection(); } }
创建实体对象 Member 类:
@Data public class Member { private String username; private String password; private String nickname; private int age; private String addr; }
创建数据库操作类 MemberDao:
public class MemberDao extends JdbcTemplate { public MemberDao(DataSource dataSource) { super(dataSource); } public List<?> selectAll(){ String sql = "select * from t_member"; return super.executeQuery(sql, new RowMapper<Member>() { public Member mapRow(ResultSet rs, int rowNum) throws Exception { Member member = new Member(); //字段过多,原型模式 member.setUsername(rs.getString("username")); member.setPassword(rs.getString("password")); member.setAge(rs.getInt("age")); member.setAddr(rs.getString("addr")); return member; } },null); } }
客户端测试代码:
public class Test { public static void main(String[] args) { MemberDao memberDao = new MemberDao(null); List<?> result = memberDao.selectAll(); } }
希望通过这两个案例的业务场景分析 , 能够帮助小伙们对模板方法模式有更深的理解。