코코코딩공부/디자인 패턴

[디자인 패턴] 전략 패턴

Ocean_ 2023. 2. 27. 19:42

들어가며

우테코에서 사다리타기 게임을 하면서 사다리 게임을 직접 실행하는 Game 도메인을 만들었다. 하지만 이 도메인은 하는일이 게임실행 + 결과값 저장 및 도출 기능을 가지고 있는 매우매우 비대한 사이즈의 도메인이였다. 그래서 이 도메인을 줄이기 위해 고민을 했었는데 카프카가 사다리타기 문제에 전략 패턴을 접목할 수 있다고 하여 알아보게 되었다.

사다리타기 클래스를 외부에서 주입해주고 테스트 할 때는 테스트용 사다리타기 클래스를 주입하여 더 간단하게 사용할 수 있을 것 같았다.


전략 패턴 정의

전략 패턴이란 실행 중에 알고리즘을 선택할 수 있게 하는 행위 소프트웨어 디자인 패턴이다.

여기서 말하는 알고리즘은 하나의 전략 이라고 생각하면 된다.

로직 실행은 인터페이스에 의존을 시키고 인터페이스를 구현한 로직들을 전달해 줌으로써 분기처리 없이 유연성을 갖출 수 가 있다.

변하지 않는 부분을 Context, 변하는 부분을 Strategy로 인터페이스로 추상화하여 진행한다. Concreate Strategy는 여러 알고리즘의 실제 구현을 의미한다.


전략 패턴 예시

전략(Strategy) GameStrategy

Map을 반환해주는 GameStrategy이다.

public interface GameStrategy {
    Map<Integer, Integer> playGame(Ladder ladder);
}

전략 콘크리트(ConcreateStrategy) ladderGameStrategy

@Override
    public Map<Integer, Integer> playGame(Ladder ladder) {
        // prizeResult 계산 공식 ~~
        return prizeResult;
    }

전략 콘크리트(ConcreateStrategy) testLadderGameStrategy

@Override
        public Map<Integer, Integer> playGame(Ladder ladder) {
            // test코드를 위해 prizeResult 계산~
            return prizeResult;
        }

위에 1개의 전략과 2개의 전략 콘크리트가 있다.

우리는 이를 Context에서 교체함으로써 사용 가능하다.

gameStrategy0 = new **ladderGameStrategy**(ladder);
gameStrategy1 = new **TestLadderGameStrategy**(ladder);

Game game = new Game(names, goal, ladder, gameStrategy0 혹은 gameStrategy1);

game 도메인은 gameStrategy를 파라메터로 받는데 이를 0번과 1번으로 갈아끼움으로써 그때그때 바꿀 수 있다.


전략 패턴 장단점

장점

  1. context의 코드 변경 없이 새로운 전략을 추가 할 수 있다.
  2. 런타임에 전략을 변경할 수 있다.
  3. 랜덤 테스트에 용이하다.

단점

  1. context에 적용되는 전략이 적다면 효과가 적다.
  2. app 에 들어가는 모든 전략을 알고 있어야한다.

의존성 주입이랑 다른게 뭘까?

처음에 전략 패턴을 만나고 느꼈던 것은 의존성 주입이랑 다른게 뭘까? 였다. 의존성 주입 또한 파라메터로 전달해줌으로써 갈아끼우듯이 사용할 수 있다고 생각했기 때문이다.

차이

  • 의존성 주입과 전략 패턴 모두 “어떠한 것을 쉽게 교체하기 위한 디자인패턴”을 의미한다.
  • 하지만 전략 패턴은 동일 행동( 교통의 MOVE , STOP ) 등을 다양한 전략으로 인터페이스를 만들며, 의도에 초점을 맞추는 것이다.
  • 의존성 주입은 일부 행동을 구현하고 단순하게 의존성만 주입하는 것이다.

나가며

디자인 패턴은 소프트웨어공학 수업 때 많이 들었던 것 같은데 기억이 하나도 안난다.. 열심히 공부해서 실전에 적용해보고 싶다.