模版方法模式解密:编写可复用、可维护的代码新境界!

文章目录

  • 一、概念
  • 二、生活中应用场景
  • 三、角色
  • 四、代码实现
  • 五、模版方法模式实现JDBC的操作
    • 1. 创建约束ORM逻辑的接口RowMapper
    • 2.创建封装了所有处理流程的抽象类JdbcTemplate
    • 3.创建实体对象Member类
    • 4.创建数据库操作类MemberDao
    • 5. 客户端测试代码
  • 总结
    • 优点
    • 缺点


一、概念

  1. 属于行为型设计模式
  2. 本质抽象封装流程,具体实现。也就是用抽象类将一个固定流程封装起来,具体步骤由不同的子类实现。
  3. 实现是通过类的继承。

二、生活中应用场景

炒菜:洗锅——>点火——>热锅——>上油——>下原料——>翻炒——>放调料——>出锅

三、角色

抽象模板(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;
    }

    @Override
    protected void checkHomework() {
        System.out.println("检查Java作业");
    }

    @Override
    protected boolean needCheckHomework() {
        return super.needCheckHomework();
    }
}

Python课程实现类:

public class PythonCourse  extends AbstractCourse{
    @Override
    protected 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>() {
            @Override
            public 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);

    }
}

总结

优点

  1. 将相同处理逻辑封装到抽象父类中,提高代码的复用性
  2. 不同的代码放到子类中,通过子类扩展增加新的行为,提高代码的扩展性。

缺点

  1. 类数目的增加,每一个抽象类都需要一个子类来实现,这样导致类的个数增加,增加了系统实现的复杂度
  2. 继承关系的自身缺点,如果父类添加新的抽象方法,所有子类都要改一遍。

你可能感兴趣的:(设计模式,java,开发语言)