Java design patterns 9 - Template Method Pattern

Template Method Pattern

definition

We define the skeleton of an algorithm in a process, while deferring some steps to subclasses.

Template methods such subclasses without changing the structure of the algorithm, some of the steps of the algorithm are redefined.

structure

AbstractClass: contains the function template abstract template method and two methods used.

templeteMethod (): calls two abstract function.

void templeteMethod() {
    primitiveOperation1();
    primitiveOperation2();
}

ConcreteClass: two abstract methods specific implementation, such a class can be many.

application

The method of the template pattern is immutable logic code or similar code pulled out and placed in an abstract base class and a variable portion of the abstract methods defined for it, encapsulated in a step of the algorithm, and to allow subclasses to the variable part provides an implementation.

To query the database using JDBC an example, FIG red frame code immutable part in all JDBC query is the same. The rest of the code will vary depending on the actual operation.

So we use the template method pattern to reconstruct it.

public abstract class JDBCTemplete {
    protected String sql = "select * from sys_privilege";
    protected Connection conn = null;
    protected PreparedStatement pstmt = null;
    protected ResultSet rs = null;

    public final Object execute() throws SQLException {
        getConnection();
        getprepareStatement();
        getResultSet();
        Object obj = handle();
        if (isPrint()) {
            printData();
        }
        close();
        return obj;
    }

    public boolean isPrint() {
        return true;
    }

    public void setSql() {}

    public abstract Object handle () throws SQLException;

    public void getConnection() {
        conn = JDBCUtils.getConn();
    }

    public void getprepareStatement() throws SQLException {
        pstmt = conn.prepareStatement(sql);
    }

    public void getResultSet() throws SQLException {
        rs = pstmt.executeQuery();
    }

    public void printData() throws SQLException {
        int columnCount = rs.getMetaData().getColumnCount();

        rs.beforeFirst();
        while (rs.next()) {
            for (int i = 0; i < columnCount; i++) {
                System.out.print(rs.getString(i + 1) + " ");
            }
            System.out.println();
        }
    }

    public void close() throws SQLException {
        if (rs != null) {
            rs.close();
        }

        if (pstmt != null) {
            pstmt.close();
        }

        if (conn != null) {
            conn.close();
        }
    }
}

This template method contains six steps:

  1. findAndPrintAll () is a fixed step algorithm, it is defined as the final step of modifying a subclass to prevent execution order.

  2. getConnection () Gets the Connection object.

  3. getprepareStatement () Gets PrepareStatementd object.

  4. getResultSet () Retrieves a ResultSet object.

  5. handle () primary query logic.

  6. print () print data.

  7. close () Closes resources.

  8. isPrint () hook function decide whether to print the data.

  9. setSql () custom SQL query hook function.

Now use this template to implement a process: All data package query the database in the User object and returns a ArrayList list, no print data.

public class User {
    private Integer id;
    private String name;
    private String url;

    //省略getter和setter
}

Data stored in the database:

id privilege_name privilege_url
1 User Management /users
2 Role Management /roles
3 System Log /logs
4 Maintenance personnel /persons
5 Maintenance Unit /companies
public class Templete extends JDBCTemplete {
    @Override
    public boolean isPrint() {
        return false;
    }

    @Override
    public Object handle() throws SQLException {
        ArrayList<User> users = new ArrayList<>();

        while (rs.next()) {
            User user = new User();
            user.setId(Integer.valueOf(rs.getString(1)));
            user.setName(rs.getString(2));
            user.setUrl(rs.getString(3));
        }

        return users;
    }
}

Test categories:

public class Main {
    public static void main(String[] args) {
        Templete templete = new Templete();
        try {
            ArrayList<User> users = (ArrayList<User>) templete.execute();
            users.forEach(System.out::println);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

Output:

User{id=1, name='用户管理', url='/users'}
User{id=2, name='角色管理', url='/roles'}
User{id=3, name='系统日志', url='/logs'}
User{id=4, name='人员维护', url='/persons'}
User{id=5, name='单位维护', url='/companies'}

After using the template method pattern, the main business of the code will become very simple.

to sum up

  1. Protected abstract class is defined in the order algorithm approach is not modified by subclasses.

  2. 分离可变及不可变部分,让子类自己决定可变部分的实现。

  3. 让算法的具体实现对子类开放,对其他类关闭。

  4. 在模板方法中可以定义一些钩子函数,来修改模板方法的执行逻辑而不是执行顺序。

发布了14 篇原创文章 · 获赞 0 · 访问量 99

Guess you like

Origin blog.csdn.net/aaacccadobe/article/details/104017561