템플릿 메서드 패턴의 단점을 보완한 전략 패턴이다.
템플릿 메서드 패턴과 추구하는 목표는 동일하다.
변하는 부분과 변하지 않는 부분의 로직을 분리한다.
템플릿 메서드 패턴은 이를 상속으로 구현했다면 전략 패턴은 이를 인터페이스로 구현한다.
public interface Strategy {
void call();
}
해당 인터페이스를 구현해 변하는 부분을 코드로 구현한다.
public class StrategyLogic1 implements Strategy {
@Override
public void call() {
log.info("비즈니스 로직 1 실행");
}
}
public class ContextV1 {
private 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);
}
}
public void strategyV1() {
Strategy strategyLogic1 = new StrategyLogic1();
ContextV1 contextV1 = new ContextV1(strategyLogic1);
context1.execute();
}
위와 같은 방식은 '선 조립 후 실행'하는 방식이다.
전략을 조금 더 유연하게, 실행 시점에 원하는 전략을 전달하기 위해서는 '조립과 동시에 실행'하는 것이 더 좋을 듯 하다.
기존 위 코드는 생성자로 구현체의 Strategy를 받고 있다.
이를 실행할 메서드의 파라미터로 받게 변경하면 '조립과 동시에 실행'이 가능하다.
추가로 템플릿 메서드 패턴과 동일하게 익명 내부클래스 -> 람다식으로 코드를 줄일 수 있다.
이렇게 람다로 변경하려면 인터페이스 내에 메서드가 1개만 있어야 한다.
Strategy 인터페이스는 메서드가 1개만 있으므로 람다식으로 코드를 작성이 가능하다.
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);
}
}
public void strategy() {
ContextV2 context = new Context2();
context.execute(() -> log.info("비즈니스 로직1 실행"));
context.execute(() -> log.info("비즈니스 로직2 실행"));
}
'Computer Science > Design Pattern' 카테고리의 다른 글
[디자인 패턴] 데코레이터 패턴 (feat. Spring) (0) | 2024.01.04 |
---|---|
[디자인 패턴] 프록시 패턴 (feat. Spring) (0) | 2023.12.28 |
[디자인 패턴] 템플릿 메서드 패턴 (feat. Spring) (0) | 2023.12.14 |
이터레이터 패턴(Iterator Pattern) (0) | 2022.07.05 |
팩토리 패턴 (0) | 2022.07.05 |