공부한것들을 정리하는 블로그 입니다.
토비의스프링3.1 3장. 템플릿 본문
#토비의 스프링
- 3장 템플릿
3. 개방 폐쇄 원칙(OCP)
- 변화에 대해 유연해야 한다.
- 3장에서 다룰 템플릿은 변화가 일어나지 않는 부분을 변경이 자주 일어나는 부분으로부터 독립시키는 방법이다.
3.1 다시 보는 초난감 DAO
- 예외처리
- 예외가 발생하더라도, 사용완료한 리소스(DB 커넥션 같이 제한적인)를 반환하도록 해야함
try catch finally문을 통해 예외 발생에 리소스를 반환할 수 있도록 대처했다. 그러나...
3.2 변하는 것과 변하지 않는 것
- 코드가 복잡하며 중복되는 로직 발생
- 변하지 않는 부분을, 변하는 부분으로부터 분리 : 템플릿 메서드 패턴
템플릿 메서드 패턴의 적용
- 상속을 통해 기능을 확장
- 변하지 않는 부분 : 슈퍼클래스
- 변하는 부분 : 추상 메서드로 두어 상속을 통해 오버라이드하여 사용
전략 패턴(Strategy Pattern)
- OCP를 지키면서 유연하고 확장성을 모두 가져갈 수 있다.
- 변하지 않는 부분 : 컨텍스트에 해당(전략IF를 의존)
- 변하는 부분 : 전략에 해당(인터페이스 IF)
- 변하는 부분을 전략IF를 통해 외부의 전략 구현체 클래스에 위임한다.
DI 적용을 위한 클라이언트/컨텍스트 분리
- 전략 패턴은 Context가 사용할 전략을 Client가 결정하는 것이 일반적이다.
- client -> context : 구체적인 전략 제공(전략IF의 구현체인 전략을 선택, 생성 후 주입)
- context -> 전략IF : 컨텍스트 정보 제공
3.3 JDBC 전략 패턴의 최적화
전략과 클라이언트의 동거
- 전략(DAO)마다 클래스 파일을 생성해야 하는 번거로움이 있다.
=>
클래스의 내부 클래스 : 스코프가 클래스에 속해있다.
- 로컬 클래스 : 스코프가 메소드에 속해있다.
- 익명 내부 클래스 : 선언 위치에 따라 스코프가 다름
3.4 컨텍스트와 DI
클래스 분리
- 스프링 빈으로 DI
- (의존 관계 : 왼쪽이 오른쪽을 의존중) UserDao -> jdbcContext -> dataSource
수동으로 DI하기
- 스프링 DI를 이용
- 의존관계가 설정파일에 명확하게 드러난다.
- 구체적인 클래스와의 관계가 직접 노출되는 문제가 있다.
- DAO코드를 이용한 수동 DI
- 장점 : DAO 내부에서 DI가 이루어지기 때문에 관계와 전략을 외부에 감출 수 있다.
- 단점 : 싱글톤으로 만들기가 번거롭고 여러 오브젝트에서 공유하기 어려움
3.5 템플릿과 콜백
템플릿/콜백 패턴 : 지금까지 전략패턴을 익명 클래스를 통해 재사용할 부분과 변화가 잦은 부분을 분리하고, 익명 클래스를 통해 전략을 구성하는 방식을 템플릿/콜백 패턴이라고 부른다.
3.5.1 템플릿/콜백의 동작원리
고정된 작업 흐름을 가진 코드를 재사용한다는 의미의 템플릿 내부에서 콜백 오브젝트가 호출되면서 동작
- 변하지 않는 부분 : 템플릿
- 전략 패턴의 컨텍스트 ( client(DI) -> context -> strategy(생략) -> strategy implements(콜백) )
- 변하지 않는 부분(재활용 가능한 부분) : 콜백
- 단일 메서드를 가진 인터페이스를 구현한 '익명 내부 클래스' 구조
일반적인 DI VS 템플릿/콜백
- 템플릿 콜백 패턴은 DI+전략패턴의 유니크한 패턴으로 이해하는 것이 좋다.
- 편리한 콜백의 재활용. 하지만 익명 내부 클래스 때문에 코드를 작성하고 읽기가 조금 불편
익명 클래스는 최선일까?
- 일반적으로 응집력이 높은 코드를 작성하기 위해서 성격이 다른 코드는 분리하는 편이 낫지만,
- 지금의 경우는 응집력이 강한 코드기 때문에 한 곳에 모여있는 것이 좋다.
- 구체적인 구현, 전략패턴, DI, 익명 내부 클래스 등은 숨기고 외부에선 메서드 호출로 이 모든 구현을 쉽게 누릴 수 있도록 노출한다.
3.5.3 템플릿/콜백의 응용
스프링은 템플릿/콜백 패턴을 적극적으로 활용하는 프레임워크
- 고정 된 작업 흐름을 갖고 있으면서 반복되는 코드가 있다면, 분리할 방법을 생각해보는 습관을 길러보자
- 템플릿/콜백 패턴의 주요 대상 - try/catch/finally를 사용하는 코드
중복의 제거와 템플릿/콜백 설계
- 추가 요구사항이 들어오면? 코드 복붙?? X
- 템플릿/콜백 패턴 적용
템플릿/콜백의 재설계
제네릭스를 이용한 콜백 인터페이스
- 결과 타입을 Integer뿐만 아니라 다양한 타입으로 받고 싶다면? 제네릭 사용
3.6 스프링의 JdbcTemplat
스프링은 JDBC를 이용하는 DAO에서 사용가능한 다양한 템플릿과 콜백을 제공
JdbcTemplate : JdbcContext와 유사하지만 훨씬 강력하고 편리한 기능 제공
정리하기
- 고정된 작업 흐름을 구현하면서 반복되는 코드가 있다면 먼저 메서드로 분리해보자.
- 일부 작업이 자주 바뀐다면, 인터페이스를 끼고 전략 패턴을 적용하자.
- DI로 의존관계를 관리하도록 해보자.
- 한 어플리케이션 내에서 바뀌는 부분이 여러 종류가 만들어 질 수 있다면 템플릿/콜백 패턴을 적용해보자.
3.7 정리
- JDBC와 같은 예외가 발생할 가능성이 있으며 공유 리소스의 반환이 필요한 코드는 반드시 try/catch/finally 블록으로 관리해야 한다.
- 일정한 작업 흐름이 반복되면서 그중 일부 기능만 바뀌는 코드가 존재한다면 전략 패턴을 적용한다. 바뀌지 않는 부분은 컨텍스트로, 바뀌는 부분은 전략으로 만들고 인터페이스를 통해 유연하게 전략을 변경할 수 있도록 구성한다.
- 같은 애플리케이션 안에서 여러 가지 종류의 전략을 다이내믹하게 구성하고 사용해야 한다면 컨텍스트를 이용하는 클라이언트 메소드에서 직접 전략을 정의하고 제공하게 만든다.
- 클라이언트 메소드 안에 익명 내부 클래스를 사용해서 전략 오브젝트를 구현하면 코드도 간결해지고 메소드의 정보를 직접 사용할 수 있어 편리하다.
- 컨텍스트가 하나 이상의 클라이언트 오브젝트에 사용된다면 클래스를 분리해서 공유하도록 만든다.
- 컨텍스트는 별도의 빈으로 등록해서 DI 받거나 클라이언트 클래스에서 직접 생성해서 사용한다. 클래스 내부에서 컨텍스트를 사용할 때 컨텍스트가 의존하는 외부의 오브젝트가 있다면 코드를 이용해서 직접 DI 해줄 수 있다.
- 단일 전략 메소드를 갖는 전략 패턴이면서 익명 내부 클래스를 사용해서 매번 전략을 새로 만들어 사용하고, 컨텍스트 호출과 동시에 전략 DI를 수행하는 방식을 템플릿/콜백 패턴이 라고 한다.
- 콜백의 코드에도 일정한 패턴이 반복된다면 콜백을 템플릿에 넣고 재활용하는 것이 편리하다.
- 템플릿과 콜백의 타입이 다양하게 바뀔 수 있다면 제네릭스를 이용한다.
- 스프링은 JDBC 코드 작성을 위해 JdbcTemplate을 기반으로 하는 다양한 템플릿과 콜백을 제공한다.
- 템플릿은 한 번에 하나 이상의 콜백을 사용할 수도 있고, 하나의 콜백을 여러 번 호출할 수도 있다.
- 템플릿/콜백을 설계할 때는 템플릿과 콜백 사이에 주고받는 정보에 관심을 둬야 한다.
'Spring > 공부' 카테고리의 다른 글
토비의스프링3.1 7장. 스프링 핵심 기술의 응용 (0) | 2022.07.26 |
---|---|
토비의스프링3.1 6장. AOP (0) | 2022.07.23 |
토비의스프링3.1 5장. 서비스 추상화 (0) | 2022.07.23 |
토비의스프링3.1 4장. 예외 (0) | 2022.07.19 |
토비의스프링3.1 2장. 테스트 (0) | 2022.07.19 |
토비의스프링3.1 1장. 오브젝트와 의존관계 (0) | 2022.07.12 |
스프링과 싱글톤 컨테이너 (0) | 2022.06.16 |
객체 지향 설계와 스프링 (0) | 2022.04.24 |