Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- Android
- QueryDSL
- pointcut
- springdatajpa
- Servlet
- Proxy
- 스프링 핵심 기능
- Spring Boot
- 스프링 핵심 원리
- Exception
- JPQL
- java
- AOP
- 그리디
- SpringBoot
- jpa
- transaction
- kotlin
- http
- db
- Thymeleaf
- 스프링
- 알고리즘
- spring
- JDBC
- 자바
- 백준
- Greedy
- 인프런
- 김영한
Archives
- Today
- Total
개발자되기 프로젝트
Strategy Pattern - 3 본문
- 이전에는 Context 필드에 Strategy를 주입해서 사용했다.
- 이번에는 전략을 실행할 때 직접 파라미터로 전달해서 사용해보자.
1. ContextV2
- ContextV2 는 전략을 필드로 가지지 않는다.
- 대신에 전략을 execute(..) 가 호출될 때 마다 항상 파라미터로 전달 받는다.
/**
* 전략을 마라미터로 전달 받는 방식
*/
@Slf4j
public class ContextV2 {
public void execute(Strategy strategy){
long startTime = System.currentTimeMillis();
//비즈니스 로직 시행
strategy.call();
//비즈니스 로직 종료
long endTime = System.currentTimeMillis();
long resultTime = endTime - startTime;
log.info("resultTime = {}", resultTime);
}
}
2. Test
@Slf4j
public class ContextV2Test {
/**
* 전략 패턴 적용
*/
@Test
void strategyV1(){
ContextV2 context = new ContextV2();
context.execute(new StrategyLogic1());
context.execute(new StrategyLogic2());
}
}
20:47:23.920 [main] INFO hello.advanced.trace.strategy.code.strategy.StrategyLogic1 - 비즈니스 로직1 실행
20:47:23.922 [main] INFO hello.advanced.trace.strategy.code.strategy.ContextV2 - resultTime = 4
20:47:23.924 [main] INFO hello.advanced.trace.strategy.code.strategy.StrategyLogic2 - 비즈니스 로직2 실행
20:47:23.924 [main] INFO hello.advanced.trace.strategy.code.strategy.ContextV2 - resultTime = 0
- Context 와 Strategy 를 '선 조립 후 실행'하는 방식이 아니라
- Context 를 실행할 때 마다 전략을 인수로 전달한다.
- 클라이언트는 Context 를 실행하는 시점에 원하는 Strategy 를 전달할 수 있다.
- 따라서 이전 방식과 비교해서 원하는 전략을 더욱 유연하게 변경할 수 있다.
- 테스트 코드를 보면 하나의 Context 만 생성한다.
- 그리고 하나의 Context 에 실행 시점에 여러 전략을 인수로 전달해서 유연하게 실행하는 것을 확인할 수 있다.
3. 전략 패턴 파라미터 실행 그림
- 클라이언트는 Context 를 실행하면서 인수로 Strategy 를 전달한다.
- Context 는 execute() 로직을 실행한다.
- Context 는 파라미터로 넘어온 strategy.call() 로직을 실행한다.
- Context 의 execute() 로직이 종료된다.
4. Test - 익명 내부 클래스, 람다
/**
* 익명 내부 클래스
*/
@Test
void strategyV2(){
ContextV2 context = new ContextV2();
context.execute(new Strategy() {
@Override
public void call() {
log.info("비즈니스 로직 1 실행");
}
});
context.execute(new Strategy() {
@Override
public void call() {
log.info("비즈니스 로직2 실행");
}
});
}
/**
* 람다
*/
@Test
void strategyV3(){
ContextV2 context = new ContextV2();
context.execute(() -> log.info("비즈니스 로직 1 실행"));
context.execute(() -> log.info("비즈니스 로직2 실행"));
}
5. 정리
- ContextV1 은 필드에 Strategy 를 저장하는 방식으로 전략 패턴을 구사했다.
- 선 조립, 후 실행 방법에 적합하다.
- Context 를 실행하는 시점에는 이미 조립이 끝났기 때문에
- 전략을 신경쓰지 않고 단순히 실행만 하면된다.
- ContextV2 는 파라미터에 Strategy 를 전달받는 방식으로 전략 패턴을 구사했다.
- 실행할 때 마다 전략을 유연하게 변경할 수 있다.
- 단점 역시 실행할 때 마다 전략을 계속 지정해주어야 한다는 점이다.
6. Template
- 지금 우리가 해결하고 싶은 문제는 변하는 부분과 변하지 않는 부분을 분리하는 것이다.
- 변하지 않는 부분을 템플릿이라고 하고,
- 그 템플릿 안에서 변하는 부분에 약간 다른 코드 조각을 넘겨서 실행하는 것이 목적이다.
- ContextV1 , ContextV2 두 가지 방식 다 문제를 해결할 수 있지만, 어떤 방식이 조금 더 나아 보이는가?
- 지금 우리가 원하는 것은 애플리케이션 의존 관계를 설정하는 것 처럼 선 조립, 후 실행이 아니다.
- 단순히 코드를 실행할 때 변하지 않는 템플릿이 있고,
- 그 템플릿 안에서 원하는 부분만 살짝 다른 코드를 실행하고 싶을 뿐이다.
- 따라서 우리가 고민하는 문제는 실행 시점에 유연하게 실행 코드 조각을 전달하는 ContextV2 가 적합.
7. GitHub : 211122 Strategy Patter 3
'인프런 > [인프런] 스프링 핵심 원리 - 고급' 카테고리의 다른 글
Template CallBack - 1 (0) | 2021.11.22 |
---|---|
Template CallBack - 시작 (0) | 2021.11.22 |
Strategy Pattern - 2, 익명 내부 클래스 (0) | 2021.11.22 |
Strategy Pattern - 1 (0) | 2021.11.22 |
Template Method - 정의 (0) | 2021.11.22 |
Comments