CS 잡지식

템플릿 메서드 패턴의 단점을 극복하자 - Strategy Pattern

JIN_YOUNG _KIM 2023. 2. 20. 21:48

Strategy Pattern

Strategy Pattern  

-> 변하지 않는 부분 : Context ( 이 클래스에서 필드 등에 Strategy 구현체(변하는 코드)를 주입 받아서, 그 구현체의 메서드

(변하는 코드 )를 호출한다, 쉽게 예기해서,  컨텍스트(문맥)는 크게 변하지 않지만, 그 문맥 속에서 strategy 를 통해 일부 전

략이 변경된다 생각하면 된다 )

-> 변하는 부분 : Strategy 인터페이스

( 템플릿 메서드 패턴과 같이 상속이 아니라 인터페이스를 사용한 위임으로 문제를 해결 )

아래의 코드를 보고, 어떻게 해서 상속을 사용하지 않고 원하는 기능을 구현했는지를 살펴 보아라. 

 

public interface Strategy {

    void call(); // 변하는 부분!!!

}

 

@Slf4j
public class StrategyLogic1 implements Strategy{ // 상속 x

    @Override
    public void call() { // 변하는 부분(Strategy 인터페이스) 구현!

    log.info("비지니스 로직1 실행");

    }

}

 

@Slf4j
public class StrategyLogic2 implements Strategy{ // 상속 x

    @Override
    public void call() { // 변하는 부분(Strategy 인터페이스) 구현!

    log.info("비지니스 로직2 실행");

    }
    
}

 

@Slf4j
public class ContextV1 {

    private Strategy 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);

    }
}

전략 패턴의 핵심은 Context 는 Strategy 인터페이스에만 의존한다는 점이다.

덕분에 Strategy 의 구현체를 변경하거나 새로 만들어도 Context 코드에는 영향을 주지 않는다

왜냐하면, 구현체가 변경이 되어도 DI를 통하여 변경체만 바꿔 주면 되고, Context 클래스 코드, 즉 클라이언트 코드는 전혀

바꿀 필요가 없기 때문이다.