[Java] 전략 패턴 정리

🔥Log·2023년 12월 27일

디자인 패턴

목록 보기
3/5

☕ 개요


전략 패턴은 공통 로직을 Context라고 부르는 곳에 두고, 변하는 부분을 Strategy라는 인터페이스로 선언한다. 그리고 이 인터페이스를 다양한 구현체로 구현해서 기능을 수행한다.
Strategy를 구현한 구현체의 개수만큼 전략이 생기게 되는 것이고, 상황에 맞게 알맞은 전략을 사용한다는 개념의 패턴이라고 볼 수 있다.

예시 코드를 통해서 좀 더 자세히 알아보도록 하자.

💡 템플릿 메서드 패턴이 "상속"을 통해서 중복을 제거했다면, 전략 패턴은 역할의 "위임"을 통해서 중복을 제거한다.


🧐 전략 패턴 예시


1. 가정

이전에 작성했던 템플릿 메서드 패턴 글과 마찬가지로, 서로 다른 2개의 기능이 존재하고, 이 기능들이 실행되는 시간을 측정해야되는 상황에 처했다고 가정해보자.

2. Strategy 인터페이스 만들기

public interface Strategy {
    void run();
}

먼저, 아주 간단하게 전략 인터페이스를 하나 만들어주자.

3. 구현 클래스 만들기

위 인터페이스를 상속해서 서로 다른 2개의 구현 클래스를 만들어주자.

public class Strategy1 implements Strategy{
    @Override
    public void run() {
        System.out.println("전략1, 로직 실행");
    }
}
public class Strategy2 implements Strategy{
    @Override
    public void run() {
        System.out.println("전략2, 로직 실행");
    }
}

4. Context 만들기

공통된 로직이 담길 Context 역할의 클래스를 만들어주자.

@Slf4j
@AllArgsConstructor
public class Context {

    private Strategy strategy;

    public void execute() {
        long startMs = System.currentTimeMillis();
        strategy.run(); // ⭐
        long endMs = System.currentTimeMillis();
        log.info("SpendMs={}", endMs - startMs);
    }

}

상황에 맞는 Strategy 구현 클래스를 생성자의 매개변수로 넘기도록 구성하였다.

5. 테스트 코드로 동작 확인하기

import hello.springaop.pattern.strategy.code.Context;
import hello.springaop.pattern.strategy.code.Strategy1;
import hello.springaop.pattern.strategy.code.Strategy2;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

@Slf4j
public class StrategyTest {

    @Test
    @DisplayName("strategyTest")
    public void strategyTest() throws Exception {
        Strategy1 strategy1 = new Strategy1();
        Strategy2 strategy2 = new Strategy2();

        Context context1 = new Context(strategy1);
        Context context2 = new Context(strategy2);

        context1.execute();
        context2.execute();
    }

}

위와 같이 테스트 코드를 작성해서 구동해보면 아래와 같이 예상한대로 기능별 소요 시간이 잘 찍히는 것을 확인할 수 있다.


🍃 스프링과 전략 패턴


위의 과정들을 통해서 전략 패턴의 예시와 동작 방식을 확인해보았다.
이러한 전략 패턴은 스프링에서 매우 많이 사용되는 패턴이다.

바로 스프링에서 가장 중요한 개념 중에 하나인 DI(Dependency injection)이다.

위의 예시에서도 확인할 수 있듯이, Strategy를 인터페이스화 함으로써 Context와 Strategy는 완변히 독립적인 구조를 갖고 있다. 스프링 DI에서도 이 특징을 활용하고 있는 것이고, 이러한 특징 덕분에 개발자는 객체 지향적인 개발이 가능해진다. 🤗


🙏 참고


0개의 댓글