文章目录
- 一、概念
- 二、生活中应用场景
- 三、角色
- 四、代码实现
- 五、模版方法模式实现JDBC的操作
- 1. 创建约束ORM逻辑的接口RowMapper
- 2.创建封装了所有处理流程的抽象类JdbcTemplate
- 3.创建实体对象Member类
- 4.创建数据库操作类MemberDao
- 5. 客户端测试代码
- 总结
- 优点
- 缺点
一、概念
- 属于行为型设计模式
- 本质抽象封装流程,具体实现。也就是用抽象类将一个固定流程封装起来,具体步骤由不同的子类实现。
- 实现是通过类的继承。
二、生活中应用场景
炒菜:洗锅——>点火——>热锅——>上油——>下原料——>翻炒——>放调料——>出锅
三、角色
抽象模板(AbstractClass):抽象模板列,定义了一套算法框架/流程;
具体实现(ConcreteClass):具体实现类,对算法框架/流程的某些步骤进行了实现。
四、代码实现
以在线课程为例
抽象模板AbstractCourse
public abstract class AbstractCourse {public final void createCourse(){//1. 发布预习资料postPreResource();//2. 制作课件createPPT();//3. 直播授课liveVideo();//4. 上传课后资料postResource();//5. 布置作业postHomework();if(needCheckHomework()){checkHomework();}}/*** 检查作业*/protected abstract void checkHomework();//钩子方法/*** 判断是否需要检查作业*/protected boolean needCheckHomework(){return true;}protected void postHomework(){System.out.println("布置作业");}protected void postResource(){System.out.println("上传课后资料");}protected void liveVideo(){System.out.println("直播授课");}protected void createPPT(){System.out.println("制作课件");}protected void postPreResource(){System.out.println("发布预习资料");}
}
具体实现:
Java课程实现类
public class JavaCourse extends AbstractCourse{private boolean needHomework=false;public void setNeedHomework(boolean needHomework) {this.needHomework = needHomework;}@Overrideprotected void checkHomework() {System.out.println("检查Java作业");}@Overrideprotected boolean needCheckHomework() {return super.needCheckHomework();}
}
Python课程实现类:
public class PythonCourse extends AbstractCourse{@Overrideprotected void checkHomework() {System.out.println("检查Python作业");}
}
客户端测试代码
public class Test {public static void main(String[] args) {System.out.println("======架构师课程======");JavaCourse javaCourse = new JavaCourse();javaCourse.setNeedHomework(false);javaCourse.createCourse();System.out.println("======Python课程======");PythonCourse pythonCourse = new PythonCourse();pythonCourse.createCourse();}
}
五、模版方法模式实现JDBC的操作
1. 创建约束ORM逻辑的接口RowMapper
public interface RowMapper<T> {/*** 将 ResultSet 中的行映射为一个对象 T* @param rs ResultSet 对象* @param rowNum 行数* @return 映射后的对象 T* @throws Exception 抛出异常*/T mapRow(ResultSet rs, int rowNum) throws Exception;
}
2.创建封装了所有处理流程的抽象类JdbcTemplate
public class JdbcTemplate {@SuppressWarnings("all")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.createStatement(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<>();int rowNum=0;while (rs.next()) {Object obj=rowMapper.mapRow(rs, rowNum++);result.add(obj);}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 createStatement(Connection conn, String sql) throws SQLException {return conn.prepareStatement(sql);}private Connection getConnection() throws SQLException {return this.dataSource.getConnection();}
}
3.创建实体对象Member类
public class Member {private String username;private String password;private String nickname;private int age;private String address;public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getNickname() {return nickname;}public void setNickname(String nickname) {this.nickname = nickname;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}
}
4.创建数据库操作类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>() {@Overridepublic Member mapRow(ResultSet rs, int rowNum) throws Exception {Member member = new Member();member.setUsername("username");member.setPassword("password");member.setAge(rs.getInt("age"));member.setAddress(rs.getString("address"));return member;}},null);}
}
5. 客户端测试代码
public class Test {public static void main(String[] args) {MemberDao memberDao = new MemberDao(null);List<?> result=memberDao.selectAll();System.out.println(result);}
}
总结
优点
- 将相同处理逻辑封装到抽象父类中,提高代码的复用性
- 不同的代码放到子类中,通过子类扩展增加新的行为,提高代码的扩展性。
缺点
- 类数目的增加,每一个抽象类都需要一个子类来实现,这样导致类的个数增加,增加了系统实现的复杂度
- 继承关系的自身缺点,如果父类添加新的抽象方法,所有子类都要改一遍。