장점

템플릿/ 콜백 방식에서 아쉬운 점

콜백의 분리와 재활용

복잡한 익명 내부 클래스의 사용을 최소화할 수 있는 방법을 찾아보자.

public void deleteAll() throws SQLException {
  this.jdbcContext.workWithStatementStrategy(
      new StatementStrategy() {
        @Override
        public PreparedStatement makePreparedStatement(Connection c) throws SQLException {
          return c.prepareStatement("delete from users");
        }
      }
  );
}

⇒ SQL 문장만 파라미터로 받아서 바꿀 수 있게 하고 메서드 내용은 전체와 분리해 별도의 메서드로 만들어보자

변하지 않는 부분 분리, executeSql 메서드

public void deleteAll() throws SQLException {
  executeSql("delete from users");
}

private void executeSql(final String query) throws SQLException{
  this.jdbcContext.workWithStatementStrategy(
      new StatementStrategy() {
        @Override
        public PreparedStatement makePreparedStatement(Connection c) throws SQLException {
          return c.prepareStatement(query);
        }
      }
  );
}

콜백과 템플릿의 결합

재사용 가능한 콜백을 담고 있는 메서드라면 DAO 가 공유할 수 있는 템플릿 클래스 안으로 옮겨도 된다.

템플릿은 JdbcContext 클래스가 아니라 workWithStatementStrategy() 메소드 → jdbcContext 클래스로 콜백 생성과 템플릿 호출이 담긴 executeSql() 메소드를 옮겨도 문제되지 않는다.

// DAO 클래스
  public void deleteAll() throws SQLException {
    this.jdbcContext.executeSql("delete from users");
  }

JdbcContext 안에 클라이언트와 템플릿, 콜백이 모두 공존하면서 동작하는 구조가 되었다.

UserDao.deleteAll() -(SQL query)→ jdbcContext.executeSql(query) : 익명 내부 클래스 콜백