
전략 패턴

- 전략 패턴은 변하지 않는 부분을 Context 라는 곳에 두고, 변하는 부분을 Strategy 라는 인터페이스를 만들고 해당 인터페이스를 구현하도록 해서 문제를 해결한다.
- 상속이 아니라 위임으로 문제를 해결하는 것이다.
- 전략 패턴에서 Context 는 변하지 않는 템플릿 역할을 하고, Strategy 는 변하는 알고리즘 역할을 한다
- Context(문맥)는 Strategy를 가지고 있고 외부에서 원하는 것을 주입하여 사용하면 된다
- 스프링의 의존관계 주입이 바로 이 전략패턴을 쓰는 방법이다
- 이 방식은 Context 와 Strategy 를 실행 전에 원하는 모양으로 조립해두고, 그 다음에 Context 를 실행하는 선 조립, 후 실행 방식에서 매우 유용하다.
예)
@Test
void strategyV0() {
logic1();
logic2();
}
private void logic1() {
long startTime = System.currentTimeMillis();
log.info("비즈니스 로직1 실행");
long endTime = System.currentTimeMillis();
long resultTime = endTime - startTime;
log.info("resultTime={}", resultTime);
}
private void logic2() {
long startTime = System.currentTimeMillis();
log.info("비즈니스 로직2 실행");
long endTime = System.currentTimeMillis();
long resultTime = endTime - 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 실행");
}
}
@Slf4j
public class ContextV1 {
Strategy strategy;
public ContextV1(Strategy strategy) {
this.strategy = strategy;
}
public void execute() {
long startTime = System.currentTimeMillis();
strategy.call();
long endTime = System.currentTimeMillis();
long resultTime = endTime - startTime;
log.info("resultTime={}", resultTime);
}
}
@Test
void strategyV1() {
StrategyLogic1 strategyLogic1 = new StrategyLogic1();
ContextV1 context1 = new ContextV1(strategyLogic1);
context1.execute();
StrategyLogic2 strategyLogic2 = new StrategyLogic2();
ContextV1 context2 = new ContextV1(strategyLogic2);
context2.execute();
}

익명 내부 클래스
@Test
void strategyV3() {
ContextV1 context1 = new ContextV1(new Strategy() {
@Override
public void call() {
log.info("비즈니스 로직1 실행");
}
});
ContextV1 context2 = new ContextV1(new Strategy() {
@Override
public void call() {
log.info("비즈니스 로직2 실행");
}
});
context1.execute();
context2.execute();
}
@Test
void strategyV4() {
ContextV1 context1 = new ContextV1(() -> log.info("비즈니스 로직1 실행"));
ContextV1 context2 = new ContextV1(() -> log.info("비즈니스 로직2 실행"));
context1.execute();
context2.execute();
}