委派模式与模板模式(4)

上面的代码中有个钩子方法可能有些小伙伴还不是太理解 , 在此我稍作解释。设计钩子方法的主要


目的是用来干预执行流程 , 使得我们控制行为流程更加灵活, 更符合实际业务的需求。 钩子方法的返回


值—般为适合条件分支语句的返回值 (如 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();
    }
}


希望通过这两个案例的业务场景分析 , 能够帮助小伙们对模板方法模式有更深的理解。

上一篇:策略模式和责任链模式(2)


下一篇:Docker——网络通信(五)(1)