浅谈JAVA设计模式之模板模式

通常很多需求存在公共的逻辑处理,也存在有差异的部分。我们希望通过提取公共的逻辑部分,减少代码的重复性。
下面通过一个印刷书本的需求来对模板模式进行简单的说明。

简单了解模板模式

BookPrintTemplate.java 模板类

public abstract class BookPrintTemplate{
    public void printBook() {
        //1.准备纸张
        this.preparePage();
        //2.书本内容
        String content = this.getContent();
        //3.印刷书本
        this.print(content);
    }

    public abstract String getContent();

    private void preparePage() {
        System.out.println("准备纸张");
    }

    private void print(String content) {
        System.out.println(content);
    }
}

SanmaoBook.java

public class SanmaoBook extends BookPrintTemplate {

    @Override
    public String getContent() {
        return "<<三毛>>";
    }
}

通过继承abstract类,实现abstract方法,提取公共逻辑部分代码,减少重复代码。

很多心细的小伙伴会发现,模板模式跟策略模式非常相似。需要说明的是,站在接口设计者的角度来讲,模板模式更加注重的是定义过程,而策略模式是由设计者定义完成的多种策略,调用者只能选择其中某一种策略进行使用。

JdbcTemplate简单实现

JdbcTemplate是典型的模板模式写法,下面我们通过简单实现JdbcTemplate类,来感受一下模板模式的魅力。

RowMapped.java

public interface RowMapped<T> {
    public T rowMap(ResultSet resultSet, int rowNum);
}

Order.java

public class Order {
    String orderId;
    String title;
    double price;

    public String getOrderId() {
        return orderId;
    }

    public void setOrderId(String orderId) {
        this.orderId = orderId;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }
}

JdbcTemplate.java

public class JdbcTemplate {

    private DataSource dataSource;

    public JdbcTemplate(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public List<?> select(String sql, RowMapped<?> rowMapped, Object[] values) {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        try{
            connection = this.getConnection();
            preparedStatement = this.createPreparedStatement(connection, sql);
            resultSet = this.executeQuery(preparedStatement, values);
            int i = 0;
            List<?> list = this.columnMapped(resultSet, rowMapped, i);
            return list;
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            try{
                this.closeResultSet(resultSet);
                this.closePreparedStatement(preparedStatement);
                this.closeConnection(connection);
            }catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    private Connection getConnection() throws SQLException {
        return this.dataSource.getConnection();
    }

    private PreparedStatement createPreparedStatement(Connection connection, String sql) throws SQLException {
        return connection.prepareStatement(sql);
    }

    private ResultSet executeQuery(PreparedStatement preState, Object[] values) throws SQLException {
        for(int i=0; i<values.length; i++) {
            preState.setObject(i+1, values[i]);
        }
        return preState.executeQuery();
    }

    private List<?> columnMapped(ResultSet resultSet, RowMapped<?> rowMapped, int rowNum) throws SQLException {
        List<Object> list = new ArrayList<>();
        while(resultSet.next()) {
            Object o = rowMapped.rowMap(resultSet, rowNum);
            list.add(o);
        }
        return list;
    }

    private void closeResultSet(ResultSet resultSet) throws SQLException {
        if(resultSet != null) resultSet.close();
    }

    private void closePreparedStatement(PreparedStatement preState) throws SQLException {
        if(preState != null) preState.close();
    }

    private void closeConnection(Connection connection) throws SQLException {
        if(connection != null) connection.close();
    }
}

OrderDao.java

public class OrderDao {

    private JdbcTemplate jdbcTemplate;
    public OrderDao(JdbcTemplate jdbcTemplate){
        this.jdbcTemplate = jdbcTemplate;
    }

    public List<?> selectAll() {
        String sql = "select order_id,title,price from tb_order";
        List<?> list = jdbcTemplate.select(sql, new RowMapped<Order>() {

            @Override
            public Order rowMap(ResultSet resultSet, int rowNum) {
                Order order = new Order();
                try {
                    order.setOrderId(resultSet.getString("order_id"));
                    order.setTitle(resultSet.getString("title"));
                    order.setPrice(resultSet.getDouble("price"));
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return order;
            }
        }, null);
        return list;
    }
}

测试类

public class OrderTest {

    public static void main(String[] args) {
        OrderDao orderDao = new OrderDao(new JdbcTemplate(new MysqlDataSource()));
        List<?> objects = orderDao.selectAll();
    }
}

模板模式在我们工作中用到得非常多,也非常实用。它将我们重复的逻辑代码统一抽取到了一个公共的父类中,将可变行为留给子类去实现,使用者能按照设计者的构想初衷去实现代码逻辑。总而言之,模板模式是一个非常使用的设计模式。

你可能感兴趣的:(JAVA设计模式)