전략 패턴은 복잡하지만 바뀌지 않는 일정한 패턴을 갖는 작업 흐름이 존재하고
그중 일부분만 자주 바꿔 사용하는 경우 적합한 구조다.
전략 패턴의 기본 구조에 익명 내부 클래스를 활용한 방식을
템플릿/콜백 패턴이라고 한다.
컨텍스트는 템플릿에 해당하고 익명 내부 클래스로 만들어지는 오브젝트를 콜백에 해당한다.
템플릿
어떤 목적을 위해 미리 만들어둔 모양이 있는 틀로 고정된 틀 안에서
특정 부분만 상황에 맞게 바꿔 사용하는 경우를 말한다.
JdbcContext처럼 공통적인 기능에서 특정 부분만 전략에 맞게 사용하는 것과 같다.
콜백
특정 로직을 담은 메서드를 실행시키기 위해 다른 오브젝트의 메서드에 전달되는 오브젝트
JdbcContext에 전달되어 실행되는 전략과 같다.
템플릿/콜백의 동작 원리
- 클라이언트(CRUD 메서드)가 콜백(익명 내부 클래스)을 생성
- 클라이언트가 템플릿(컨텍스트)에 콜백을 전달하며 호출
- 템플릿의 로직 시작 및 참조정보(JDBC 정보) 생성
- 템플릿이 콜백을 호출하며 참조정보를 전달
- 클라이언트 및 전달 받은 참조정보 등을 통해 로직 수행
- 템플릿에 로직 결과를 리턴
- 템플릿의 남은 로직 수행 및 마무리
- 클라이언트에 템플릿의 작업 결과를 리턴
콜백의 분리와 재활용
클라이언트의 메서드가 간결해지고 최소한의 로직만 갖고 있게 된다는 장점이 있지만
익명 내부 클래스를 통해 코드를 작성하는 것은 익숙한 방식이 아니기도해서
코드의 작성이나 가독성이 떨어진다는 단점이 있다.
기존에 했던 작업들처럼 익명 내부 클래스를 통해 오브젝트를 만드는 코드에서
반복적으로 수행되는 작업을 분리하면 이러한 문제를 줄일 수 있다.
new StatementStrategy() {
public PreparedStatement makePreparedStatement(Connection c) throws SQLException {
return c.prepareStatement("변하는 SQL문");
}
}
위의 코드에서 SQL문을 리턴해주는 부분만 빼면 콜백 클래스의
정의와 생성은 어느 메서드에서 사용하든 일치한다는 것을 알 수 있다.
반복되는 부분인 콜백 클래스의 정의와 생성을 메서드로 분리하고
분리한 메서드의 파라미터로 변하는 부분인 SQL문을 전달하면 된다.
private void executeSql(final String query) throws SQLException {
this.jdbcContext.workWithStatementStartegy(
new StatementStrategy() {
public PreparedStatement makePreparedStatement(Connection c) throws SQLException {
return c.prepareStatement("변하는 SQL문");
}
}
);
}
이렇게 분리된 메서드를 add와 delete 등의 DAO의 메서드에서 그대로 재사용하면 된다.
public void deleteAll() throws SQLException {
executeSql("delete from users");
}
당연히 코드가 훨씬 간결해졌다.
콜백과 템플릿 결합하기
마찬가지로 executeSql 메서드도 모든 DAO 클래스에서 사용해야하는
공통적인 기능이기 때문에 공유하는 것이 좋다.
해당 메서드를 공유해서 사용할 수 있게 JdbcContext 클래스로 옮겨주기만 하면된다.
public class JdbcContext {
public void executeSql(final String query) throws SQLException {
workWithStatementStartegy(
new StatementStrategy() {
public PreparedStatement makePreparedStatement(Connection c) throws SQLException {
return c.prepareStatement("변하는 SQL문");
}
}
);
}
}
성격이 다른 코드이기 때문에 분리하는 것이 좋을 수도 있지만
하나의 목적을 위해 서로 연결되어 있는 응집력이 강한 코드이기 때문에
한 곳에 모아두는 것이 오히려 유리하다.
'Back-End > Spring' 카테고리의 다른 글
템플릿 정리 (0) | 2023.06.14 |
---|---|
JDBC Template (0) | 2023.06.13 |
컨텍스트와 DI (0) | 2023.06.13 |
전략 패턴 최적화 하기 (0) | 2023.06.13 |
템플릿 적용하기 (0) | 2023.06.13 |