티스토리 뷰

new study

템플릿 콜백 패턴

kkssry 2020. 2. 17. 17:03

JDBC API 기능을 사용하면서 나오는 중복된 코드가 발생합니다.

해당 기능은 유지면서 중복된 코드를 없애고자 디자인 패턴 중 하나인 템플릿 콜백 패턴을 적용해 보았습니다.

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class UserDao {
 
    ...
 
    public void update(User user) throws SQLException {        
        Connection con = null;
        PreparedStatement pstmt = null;
        try {
            con = ConnectionManager.getConnection();
            String sql = "UPDATE users SET password = ?, name = ?, email = ? WHERE userId = ?";
            pstmt = con.prepareStatement(sql);
            pstmt.setString(1, user.getPassword());
            pstmt.setString(2, user.getName());
            pstmt.setString(3, user.getEmail());
            pstmt.setString(4, user.getUserId());
 
            pstmt.executeUpdate();
        } finally {
            if (pstmt != null) {
                pstmt.close();
            }
 
            if (con != null) {
                con.close();;
            }
        }
    }
 
    ...
 
}
 
 

 

위 코드는 User 객체를 업데이트 하는 기능을 담당하는 메서드인데 메서드 안에서 DB와 연결하는 Connection 객체와 쿼리문 그리고 PreparedStatement객체가 모여있습니다. 메서드가 많은 기능을 담당하고 조회나 삭제 기능을 구현할때 중복된 코드가 발생합니다.

 

 

 

템플릿 콜백 패턴을 적용한 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/// UserDao객체는 user관련 쿼리문을 작성하고 JdbcTemplate 객체에 전달하도록 했습니다.
public class UserDao {
 
    ...
 
    public void insert(User user) throws SQLException {
        JdbcTemplate template = new JdbcTemplate();
 
        template.sendQuery("INSERT INTO USERS VALUES(?,?,?,?)", (pstmt) -> {
            pstmt.setString(1, user.getUserId());
            pstmt.setString(2, user.getPassword());
            pstmt.setString(3, user.getName());
            pstmt.setString(4, user.getEmail());
        });    
    }
 
    ...
 
}
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
// JDBCTemplate 객체는 쿼리문을 담당하는 객체로 분리했습니다.
 
public class JdbcTemplate {
 
...
 
public void sendQuery(String sql, PreparedStatementSetter pss) throws SQLException {
        try (Connection con = ConnectionManager.getConnection();
             PreparedStatement pstmt = con.prepareStatement(sql)) {
            pss.setValues(pstmt);
            pstmt.executeUpdate();
        }
    }
 
...
 
}
 
 
 
 
1
2
3
4
// PreParedStatementSetter객체는 PreparedStatement 객체가 클라이언트가 요청한 쿼리문에 값을 넣어 원하는 결과를
// 조회하는 기능으로 분리하였습니다. 익명 클래스로 사용할 것이기 때문에 @FunctionallInterface를 추가하여 1개의 기능만을 선언 하도록 했습니다.
 
@FunctionalInterface
public interface PreparedStatementSetter {
    void setValues(PreparedStatement pstmt) throws SQLException;
}
 

 

메서드에 선언만 되어진 인터페이스를 넘기고 해당 인터페이스를 매개변수로 받고 다른 메서드에서 인터페이스를 사용한다.

호출하는 곳에서 인터페이스를 정의 내리고 사용은 다른 메서드에서 사용함으로써 다양한 기능 구현을 하는 이점이 있다.

하지만 인터페이스의 기능이 수정되면 해당 인터페이스를 사용하는 곳에 수정을 해야하는 단점이 있다.

'new study' 카테고리의 다른 글

리플렉션  (0) 2020.02.25
PROCESS vs THREAD  (0) 2019.06.30
COOKIE vs SESSION  (0) 2019.06.24
replace vs replaceAll  (0) 2019.06.21
GET vs POST  (0) 2019.06.20
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
TAG
more
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함