Template Method Pattern of Java Design Patterns

Reprinted: https://www.cnblogs.com/qq-361807535/p/6854191.html


Introduction: I have been reading a book about spring source code in the past few days, "SPRING Technology Insider". When loading configuration files, there are different loading methods, such as loading configuration files (FileSystemXmlApplicationContext) according to the file system directory, class path loading The configuration file (ClassPathXmlApplicationContext), and the configuration file is loaded according to the project context directory (XmlWebApplicationContext). This uses the template design mode during the loading process, so let's learn the template design mode.

1. The template design pattern is defined in the book:

  Defining the skeleton of an algorithm in an operation, while deferring some steps to subclasses, template methods allow subclasses to redefine certain steps of the algorithm without changing the structure of the algorithm.

  The popular understanding is: to complete a thing, there are a fixed number of steps, but each step is different according to the object, and the implementation details are different; you can define a general method to complete the thing in the parent class, according to the completion event. The required steps call the implementation method of each step. The concrete implementation of each step is done by subclasses.

2. The class diagram of a template pattern found on the Internet as follows:

  Abstract parent class (AbstractClass): implements the template method and defines the skeleton of the algorithm.

  Concrete class (ConcreteClass): Implement abstract methods in abstract classes, that is, the specific implementation details of different objects.

    

3. Example description

  Let’s take an example: For example, cooking can be divided into three steps (1) preparation of ingredients (2) specific cooking (3) serving of dishes to guests, these three steps are the skeleton of the algorithm; however, the ingredients needed to make different dishes , the method of doing it, and how to dress it up for the guests to enjoy are all different. This is the implementation detail of the different.

  Let's implement the code as follows

 a. Let’s first write an abstract cooking parent class:  

copy code
public abstract class DodishTemplate {    
    /**
     * Specific whole process
     */
    protected void dodish(){
        this.preparation();
        this.doing();
        this.carriedDishes();
    }
    /**
     * Preparation
     */
    public abstract void preparation();
    /**
     * cooking
     */
    public abstract void doing();
    /**
     * serve
     */
    public abstract void carriedDishes ();
}
copy code

 b. Come down and make two tomato scrambled eggs (EggsWithTomato) and braised pork (Bouilli) to implement the abstract method in the parent class

copy code
/**
 * Scrambled eggs with tomatoes
 * @author aries
 */
public class EggsWithTomato extends DodishTemplate{

    @Override
    public void preparation() {
        System.out.println("洗并切西红柿,打鸡蛋。");
    }

    @Override
    public void doing() {
        System.out.println("鸡蛋倒入锅里,然后倒入西红柿一起炒。");
    }

    @Override
    public void carriedDishes() {
        System.out.println("将炒好的西红寺鸡蛋装入碟子里,端给客人吃。");
    }

}
copy code
copy code
/**
 * 红烧肉
 * @author aries
 *
 */
public class Bouilli extends DodishTemplate{

    @Override
    public void preparation() {
        System.out.println("切猪肉和土豆。");
    }

    @Override
    public void doing() {
        System.out.println("将切好的猪肉倒入锅中炒一会然后倒入土豆连炒带炖。");
    }

    @Override
    public void carriedDishes() {
        System.out.println("将做好的红烧肉盛进碗里端给客人吃。");
    }

}
copy code

  c. 在测试类中我们来做菜:

copy code
public class App {
    public static void main(String[] args) {
        DodishTemplate eggsWithTomato = new EggsWithTomato();
        eggsWithTomato.dodish();
        
        System.out.println("-----------------------------");
        
        DodishTemplate bouilli = new Bouilli();
        bouilli.dodish();
    }
}
copy code

 这样我们就实现了使用模板模式的一个完整的实例。

4. 在书本上看到过这么一个例子:

 去银行办业务,如取钱,存钱或者办卡等,基本都需要三个大的步骤(骨架),首先 (1)取号 (2)办具体业务 (3)服务评价打分,然后这三个步骤就可以抽取到父类中进行定义,(1)取号 (3)服务打分是相同操作,可以直接在父类总实现,然后(2)办具体的业务各不相同需要在子类中实现。如下我画个类图:

    takeNumber(取号),trabsact(具体业务),evaluate(评价),process(骨架方法)。

5. 模板设计模式常在数据库操作中使用,我现在使用模板模式做一个JDBC的查询模板:

  (1) 抽象查询父类 

copy code
public abstract class AbstractDao {

    /**
     * 查询
     * @param sql
     * @param params
     * @return
     */
    protected Object find(String sql, Object[] params) {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        Object obj = null;
        try {
            conn = JDBCUtils.getConnection();
            ps = conn.prepareStatement(sql);
            for (int i = 0; i < params.length; i++) {
                ps.setObject(i + 1, params[i]);
            }
            rs = ps.executeQuery();
            while (rs.next()) {
                obj = rowMapper(rs);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.free(rs, ps, conn);
        }
        return obj;
    }
    
protected abstract Object rowMapper(ResultSet rs) throws SQLException;

//同时可以添加 insert ,update 等方法 }
copy code

 (2)具体的UserDao

copy code
/**
 * userDao
 * 
 * @author aries
 *
 */
public class UserDao extends AbstractDao {

    public User findUser(int userId) {
        String sql = "select * from t_user where userId = ?";
        Object[] params = new Object[] { userId };
        Object user = super.find(sql, params);
        System.out.println((User) user);
        return (User) user;
    }

    @Override
    protected Object rowMapper(ResultSet rs) throws SQLException {
        User user = new User();
        user.setId(rs.getInt("userId"));
        user.setName(rs.getString("name"));
        user.setAge(rs.getInt("age"));
        user.setSex(rs.getString("sex"));
        user.setAddress(rs.getString("address"));
        return user;
    }
}
copy code

 (3)以上代码中用到的User类和JDBCUtil

copy code
public class JDBCUtils {
    private static String url = "jdbc:mysql://localhost:3306/jdbcstudy";
    private static String user = "root";
    private static String password = "123";

    private JDBCUtils() {
    }

    static {
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            throw new ExceptionInInitializerError(e);
        }
    }

    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(url, user, password);
    }
    
    public static void free(ResultSet rs, PreparedStatement ps, Connection conn){
        if(rs != null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(ps != null){
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        
        if(conn != null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}
copy code
copy code
/**
 * 用户类
 * 
 * @author aries
 *
 */
public class User {
    private Integer id;
    private String name;
    private Integer age;
    private String sex;
    private String address;
        
    //set...get省略    
}
copy code

 如上就使用模板模式做的查询,父类中做了算法骨架,子类中具体实现算法中的不同部分。

6. 模板模式的优点

 (1)具体细节步骤实现定义在子类中,子类定义详细处理算法是不会改变算法整体结构。

 (2)代码复用的基本技术,在数据库设计中尤为重要。

 (3) There is a reverse control structure, in which a parent class invokes the operation of its subclass, and the subclass extends the parent class to add new behaviors, which conforms to the "opening and closing principle".

7. Inadequate

    Each different implementation needs to define a subclass, which will lead to an increase in the number of classes and a larger system.


You can also refer to the learning of the template method: https://blog.csdn.net/u013565163/article/details/79285617

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325810410&siteId=291194637