토비의 스프링
토비의 스프링
[3장] 템플릿
[3.1] 다시 보는 초난감 DAO
- 예외처리하기
일반적으로 서버에서는 제한된 개수의 db 커넥션을 만들어서 재사용 가능한 풀로 관리한다.
getConnection을 clsoe(리소스 반환)해야지만 다시 풀에 넣었다가 다음 커넥션 요청 시 재사용할 수 있다.
제 때 안닫아주면 커넥션 풀에 여유가 없어지고 리소스가 모자라다는 오류를 내며 서버가 중단된다.
try-catch-finally를 통한 자원 닫아주기
[3.2] 변하는 것과 변하지 않는 것
모든 메서드마다 try-catch-finally가 반복된다.
- 메서드 추출
- 템플릿 메서드 패턴의 적용
UserDao를 상속하는 add, delete, get, count 메서드 생성
서브 클래스가 이미 컴파일(설계) 시점에 관계가 고정되어 유연성이 떨어진다. - 전략패턴의 적용
오브젝트를 분리하고 클래스 레벨에서는 인터페이스를 통해서만 의존하도록 한다.
확장을 추상화된 인터페이스에 위임- DB 커넥션 가져오기
- PreparedStatement 만들어줄 외부 기능 호출
- preparedStatement 실행
- 예외 발생 시 메서드 밖으로 던지기
- 모든 경우에 close 하기
preparedStatement 만들어주는 외부 기능이 전략
-
DI 적용을 위한 클라이언트/컨텍스트 분리
client가 구체적인 전략의 하나를 선택하고 오브젝트로 context에 전달
context는 전달받은 strategy 구현 클래스의 오브젝트 사용 - 마이크로 DI
IoC 컨테이너의 도움 없이 코드 내에서 매우 작은 다위의 코드와 메서드 간 DI가 이뤄지는 경우
[3.3] JDBC 전략 패턴의 최적화
DAO 메서드마다 새로운 statementStrategy 구현 클래스를 만들어야 하는 문제 발생, 이는 템플릿 메서드와 마찬가지로 클래스 개수 상승
부가적인 정보를 받고 싶을 때 오브젝트를 전달받는 생성자와 이를 저장해둘 인스턴스 변수를 만들어야 하는 문제 발생
- 로컬 클래스 사용
클래스 파일도 줄일 수 있고 로컬 변수를 가져다 쓸 수도 있다. - 익명 내부 클래스
딱 한 번만 사용해서 간결한 구현이 가능하다. - 중첩 클래스: 다른 클래스 내부에 정의되어 있는 클래스(static classm, inner class(member inner: 오브젝트 레벨, local: 메서드 레벨, anonymous inner: 익명))