전략 패턴

HoyongLee·2023년 2월 26일
0


변하지 않는 부분을 Context에, 변하는 부분을 Strategy라는 인터페이스를 구현하도록, 즉, 상속이 아닌 위임을 통해 변하지 않는 부분과 변하는 부분을 분리한다.

ContextStrategy인터페이스에만 의존하기 때문에 Strategy의 구현체를 변경해도 코드를 변경하지 않아도 된다. (반대로 Context가 변경되도 Strategy의 코드에 영향을 주지 않는다.)

스프링에서 의존관계 주입에 사용하는 것이 전략패턴이다.

전략 패턴의 목적
알고리즘의 제품군을 정의하고 각각의 캡슐화하여(Strategy, 인터페이스) 상호교환이 가능하게 만든다. 전략을 사용하면 알고리즘을 사용하는 클라이언트와 독립적으로 알고리즘을 변경할 수 있다.

public class Context {
	private Strategy strategy;
    
    public Context(Strategy strategy) {
    	this.strategy = strategy;
    }
    
    public execute() {
    	long startTime = 시작시간_가져온다();
        strategy.call();
        long endTime = 종료시간_가져온다();
        print(endTime - startTime);
    }
}

Context 클래스를 정의한다.

public interface Strategy {
	void call();
}

Strategy 인터페이스를 정의한다.

public class SubjectStrategy1 implements Strategy {
	@Override
    void call() {
    	핵심 기능 구현();
    }
}

public class SubjectStrategy2 implements Strategy {
	@Override
    void call() {
    	핵심 기능 구현();
    }
}

전략을 구현한다.

void run() {
	Context context1 = new Context(new SubjectStrategy1());
    Context context2 = new Context(new SubjectStrategy2());
    context1.execute();
    context2.execute();
}

위 방식은 "선 조립 후 실행" 방식이다. 스프링에서 어플리케이션의 로딩 시점에 의존관계를 주입한 후에 실제 요청을 처리하는 원리이다.

단점
조립 이후에는 전략을 변경하기 쉽지 않다. setter를 통해 변경하면 되지만, 싱글톤일 경우 동시성 이슈 등을 고려해야 한다.

public class Context {
	public execute(Strategy strategy) {
    	long startTime = 시작시간_가져온다();
        strategy.call();
        long endTime = 종료시간_가져온다();
        print(endTime - startTime);
    }
}

인자를 통해 전략을 넘겨 받으면 실행할 때 마다 인수를 전달한다.
컨텍스트를 새로 생성하지 않아도 되기 때문에 원하는 전략을 더 유연하게 변경할 수 있다.

이렇게 인자를 통해 전략을 넘겨받는 디자인 패턴을 템플릿 콜백 패턴 이라고 스프링 내에서 부른다.

  • 전략 패턴에서 템플릿(Context)과 콜백(Strategy)이 강조되는 패턴이다.
  • JdbcTemplate, RestTemplate, TransactionTemplate 등에서 사용된다.
profile
아직 반지하

0개의 댓글

관련 채용 정보