Typescript로 다시 쓰는 GoF - Strategy

아홉번째태양·2023년 8월 29일
0

Strategy패턴이란?

Strategy는 전략이며, 소프트웨어에서의 전략은 특정 기능을 어떤식으로 구현할지에 대한 알고리즘 혹은 비즈니스 로직이다.

Strategy 패턴은 하나의 목적을 가지는 여러개의 전략이 있을 때 이를 효과적으로 관리하고 또 교체하여 사용하기 편리하게 하기 위해 사용한다. 각 전략들 간에 공통된 인터페이스를 두고, 구체적인 구현체만 추가 혹은 수정하여 사용한다.


언제 쓸까?

Strategy 패턴은 굉장히 다양하게 쓰일 수 있다. 그중 대표적으로는 결제 시스템에서 결제 수단을 관리할 때, 혹은 게임에서 몬스터의 상태에 따라 행동패턴을 변화시킬 때 사용할 수 있다.



Strategy 구현

Strategy 패턴의 구조는 비교적 단순하다.

  1. Strategy 전략
    전략을 이용하는 인터페이스를 정의

  2. ConcreteStrategy 구체적인 전략
    Strategy에서 정의한 인터페이스를 구현하며, 이곳에서 구체적인 로직이나 알고리즘이 작성된다. 즉, Strategy 패턴 자체의 구조는 단순하지만, 구조보다 더 중요한 것은 ConcreteStrategy의 내용이다.

  3. Context 문맥
    Strategy의 인터페이스를 호출하며 필요에 따라 다양한 ConcreteStrategy를 가지고 있는다.


Strategy 패턴은 결제시스템을 상상하며 구조만 간단하게 구현해보기로 한다.

Strategy

우선 결제를 요청하는 메소드 pay가 정의된 전략 인터페이스를 먼저 만든다.

interface PaymentStrategy {
  pay(amount: number): void;
}

ConcreteStrategy

이제 구현체를 앞서 정의한 인터페이스를 필요한 종류만큼 작성한다. 여기서는 결제 방법이 신용카드와 페이팔 두 가지 방법이 있다고 가정하자.

class CreditCardPayment implements PaymentStrategy {
  pay(amount: number): void {
    console.log(`Paying ${amount} using Credit Card`);
  }
}

class PayPalPayment implements PaymentStrategy {
  pay(amount: number): void {
    console.log(`Paying ${amount} using PayPal`);
  }
}

Context

마지막으로 전략을 관리하고 사용하는 객체를 만든다.

class PaymentContext {
  constructor(
    private paymentStrategy: PaymentStrategy,
  ) {}

  pay(amount: number) {
    this.paymentStrategy.pay(amount);
  }

  set(strategy: PaymentStrategy) {
    this.paymentStrategy = strategy;
  }
}

Strategy 패턴의 장점이 유사한 다른 전략으로의 쉬운 교체인만큼 전략을 교체할 수 있는 메소드를 넣는 것이 좋다.

그리고 pay라는 메소드는 단순히 Strategy에서 정의한 인터페이스만을 불러오고 있는데, 다른 로직이 추가될 수도 있지만 각각의 구현체가 바뀌어도 항상 pay 메소드의 목적을 수행을 보장한다.


실행

const context = new PaymentContext(new CreditCardPayment());
context.pay(100);

context.set(new PayPalPayment());
context.pay(200);
Paying 100 using Credit Card
Paying 200 using PayPal



참고자료

Java언어로 배우는 디자인 패턴 입문 - 쉽게 배우는 Gof의 23가지 디자인패턴 (영진닷컴)

0개의 댓글