템플릿 메서드 패턴은 부모 클래스에 변하지 않는 템플릿을 두고 변하는 부분을 자식 클래스에 두어 상속을 사용함
전략 패턴은 변하지 않는 부분을 Context에 두고, 변하는 부분을 Strategy라는 인터페이스를 만들고 해당 인터페이스를 구현하여 문제를 해결. 상속이 아니라 위임으로 문제를 해결한다.
@Slf4j
public class ContextV1 {
private Strategy strategy;
public ContextV1(Strategy strategy) {
this.strategy = strategy;
}
public void execute() {
long startTime = System.currentTimeMillis();
//비지니스 로직 실행
strategy.call();
//비지니스 로직 종료
long entTime = System.currentTimeMillis();
long resultTime = entTime - startTime;
log.info("resultTime ={}", resultTime);
}
}
전략 인터페이스(변하는것)
public interface Strategy {
void call();
}
전략패턴 구현
@Slf4j
public class StrategyLogic1 implements Strategy{
@Override
public void call() {
log.info("비지니스 로직1실행");
}
}
@Slf4j
public class StrategyLogic2 implements Strategy{
@Override
public void call() {
log.info("비지니스 로직2실행");
}
}
Context는 내부에 Strategy 필드를 가지고 있고, 이 필드에 변하는 부분인 Strategy의 구현체를 주입하면된다.
전략 패턴의 핵심은 Context는 Strategy 인터페이스에만 의존한다는 점이다.
아래와 같은 형태로도 사용할 수 있다.
전략을 따로 가지지 않고, 메소드로 바로 전달한다.
@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);
}
}
아래와 같이 실행하는 시점에 해당 전략을 전달해줌으로써, 의존성을 더 줄일 수도 있다.
@Slf4j
public class ContextV2Test {
/**
* 전략 패턴 적용
*/
@Test
void strategyV1() {
ContextV2 context = new ContextV2();
context.execute(new StrategyLogic1());
context.execute(new StrategyLogic2());
}
}
'SPRING > 스프링' 카테고리의 다른 글
[스프링 핵심 원리 - 고급편] 프록시, 프록시 패턴, 데코레이터 패턴 (0) | 2022.02.16 |
---|---|
[스프링 핵심 원리-고급] 템플릿 콜백 패턴 (0) | 2022.01.27 |
[스프링 핵심 원리-고급] 템플릿 메서드 패턴 (0) | 2022.01.25 |
[스프링 핵심 원리-고급] 쓰레드 로컬 주의사항 (0) | 2022.01.22 |
[스프링 핵심 원리-고급] ThreadLocal (0) | 2022.01.21 |