[디자인패턴] Strategy Pattern, 전략 패턴

Chloe Choi·2021년 4월 7일
0

디자인패턴

목록 보기
8/11

배경(Why)

지도앱을 구현하고 있다. 처음엔 출발지부터 도착지까지의 경로를 "걸어서"가는 요구사항만 있었다. 그 후에 "대중교통", "자동차" 이런 선택지가 추가되었다. 처음부터 switch case문을 이용해 Navigator 클래스에 모든 알고리즘을 구현했다면 어떻게 될까?

한 알고리즘의 수정은 곧 Navigator 클래스 수정을 의미하게 되고 에러를 발생하기 쉬워진다.(Navigator는 여러 행위를 구현하게 되어 SRP를 위배)

이렇게 한 클래스가 여러 방법을 제공하는 경우엔 어떻게 구현하는 게 좋을까?

How

경로를 찾는 알고리즘을 Navigator 클래스에서 뽑아내 별도의 클래스들(a.k.a. strategies)로 만들자! Strategy라는 Interface를 구현하고 Navigator 클래스는 뽑아낸 클래스에 대한 참조를 가져 알고리즘 연산을 Strategy에 위임하는 방법을 사용하자.

다만, Navigator가 참조할 전략 클래스는 Navigator 클래스가 고르는게 아니라 클라이언트가 적절한 전략 클래스를 전달해주는 방식이다. 따라서, Navigator(a.k.a. Context)는 strategies에 대해 많이 알지 않아도 된다! 즉, Context는 Concrete strategies로부터 독립이게 되어 새로운 알고리즘을 추가하거나 기존 알고리즘을 수정하는 것이 Context에 영향을 주지 않게 된다. 👉 OCP 만족

What

위와 같이 동작하는 Strategy Pattern 이란,

행위를 클래스로 캡슐화해 동적으로 행위를 자유롭게 바꿀 수 있게 하는 패턴이다.



1. Context
Concrete Strategies 중 한 개에 대한 참조를 갖고 있으며 Strategy Interface를 통해 그 객체와 communicate
2. Strategy
Concrete Strategies의 generic interface로, Context에서 사용할 함수를 선언한다
3. Concrete Strategies
Context에서 사용하는 여러 알고리즘(행위)을 구현한다
4. Client가 Concrete Strategies 중 하나를 Context에 전달하므로 Context는 그에 대한 자세한 정보를 알고 있지 않다
5. Client
특정 전략을 객체를 Context에 전달해준다. 따라서, Context는 전략 객체 setter 클래스를 제공해야한다.

언제 쓸까?(When)

  • 한 객체 내에서 여러 알고리즘을 사용하고 런타임에 그 알고리즘을 다른 알고리즘으로 변경이 필요한 경우
    전략패턴은 객체의 행위를 런타임에 바꿀 수 있게 한다.
  • 행위에 대한 실행 방법만 다른 여러 클래스를 갖고 있는 경우
    전략패턴은 다양한 행위를 뽑아내 별도의 클래스로 만들며 비슷한 부분은 한 클래스로 둬 코드 중복을 줄일 수 있다.
  • 비즈니스 로직과 알고리즘의 구체적인 구현을 분리하고자 할 때
    전략패턴은 여러 알고리즘을 뽑아내 그에 대한 의존성을 줄인다. 따라서, 여러 클아이언트는 간단한 인터페이스를 통해 알고리즘을 실행시키고 런타임에 그것을 변경할 수 있다.
  • 조건에 따라 동일한 목적의 다른 구현을 가진 알고리즘을 진행하는 경우
    전략패턴을 통해 조건부로 실행되는 알고리즘을 별도의 클래스로 뽑아낸다.

Pros

  • 객체 내 알고리즘을 런타임에 교체할 수 있다
  • 알고리즘의 구체적인 구현과 그것을 사용하는 코드를 분리할 수 있다
  • 새로운 전략을 Context 수정없이 추가할 수 있다. 즉, OCP를 만족한다

Cons

  • 만약 거의 비슷한 두 알고리즘이 있다면 오히려 프로그램이 복잡해지는 오버헤드가 존재한다
  • ConcreteStrategy를 Context에 전달해주는 Client는 그 strategies의 차이를 인지해야 한다

예제

StrategyPatternPractice - github.com/cchloe2311

ref.

https://refactoring.guru/design-patterns/strategy

profile
똑딱똑딱

0개의 댓글