관리 메뉴

공부한것들을 정리하는 블로그 입니다.

토비의스프링3.1 3장. 템플릿 본문

Spring/공부

토비의스프링3.1 3장. 템플릿

호 두 2022. 7. 19. 01:05
반응형

#토비의 스프링
 - 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을 기반으로 하는 다양한 템플릿과 콜백을 제공한다.
  • 템플릿은 한 번에 하나 이상의 콜백을 사용할 수도 있고, 하나의 콜백을 여러 번 호출할 수도 있다.
  • 템플릿/콜백을 설계할 때는 템플릿과 콜백 사이에 주고받는 정보에 관심을 둬야 한다.

 

 

반응형
Comments