전략 패턴

킹발·2022년 10월 21일
0

Spring

목록 보기
2/2
post-thumbnail

문제 정의

UserDao는 회원 User를 추가하고, 전체 목록을 삭제하는 add(), deleteAll() 메서드를 가지고 있다. 그런데 빨간 박스를 제외하고 동일한 패턴이다.
중복된 코드를 제거하고 재사용성을 높이기 위해서 전략 패턴을 적용해보자.

리팩토링

jdbcContext() 에서 변하지 않는 부분을 동작하다가 변하는 부분은 Strategy 인터페이스를 통해 외부의 독립된 전략 클래스(AddStrategy or DeleteAllStategy)에 위임한다.

Strategy 인터페이스

  • Add()에서는 INSERT 쿼리문이 담긴 PreparedStatement 가 필요
  • DeleteAll()에서는 DELETE 쿼리문이 담긴 PreparedStatement 가 필요

👉 따라서 PreparedStatement 를 반환해주는 인터페이스를 작성한다.

public interface StatementStrategy {
    PreparedStatement makePreparedStatement(Connection conn) throws SQLException;
}

전략 클래스

AddStrategy

public class AddStrategy implements StatementStrategy {

    private User user;

    public AddStrategy(User user) {
        this.user = user;
    }

    @Override
    public PreparedStatement makePreparedStatement(Connection conn) throws SQLException {
        String sql = "INSERT INTO users(id, name, password) VALUES(?, ?, ?)";

        PreparedStatement pstmt = conn.prepareStatement(sql);
        pstmt.setString(1, user.getId());
        pstmt.setString(2, user.getName());
        pstmt.setString(3, user.getPassword());

        return pstmt;
    }
}

DeleteAllStrategy

public class DeletAllStrategy implements StatementStrategy {

    private String sql = "DELETE FROM users";

    @Override
    public PreparedStatement makePreparedStatement(Connection conn) throws SQLException {
        return conn.prepareStatement(sql);
    }
}

Context

바뀌지않는 중복되는 흐름 그대로 가져간다.
바뀌는 부분에서는 파라미터로 전달받은 인터페이스의 메서드를 호출한다.

private void jdbcContext(StatementStrategy strategy) throws SQLException {
    Connection conn = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;

    try {
        conn = cm.getConnection();
        pstmt = strategy.makePreparedStatement(conn); //전달받은 전략을 사용한다.
        pstmt.executeUpdate();
    } catch (SQLException e) {
        throw e;
    }
    close(conn, pstmt, null);
}

전략 패턴 적용

public void add(User user) throws SQLException {
    jdbcContextWithStatementStrategy(new AddStrategy(user));
}

public void deleteAll() throws SQLException {
    jdbcContextWithStatementStrategy(new DeletAllStrategy());
}

0개의 댓글