TypeScript-전략패턴(Strategy pattern)

hannah·2023년 9월 27일
0

JavaScript

목록 보기
106/121

전략패턴(Strategy pattern)

  • 객체가 할 수 있는 행위들을 전략(strategy)으로 만들어두고, 동적으로 행위의 수정이 필요한 경우 전략을 바꾸는 것만으로 수정이 가능하도록 만든 패턴이다.

전략패턴 활용 사례

  • 자판기 결제 방식을 현금 결제에서 카드 결제로 변경할 때, Pay 메소드 구현 변경이 필요하다.
  • 메소드 수정 방식의 문제점
    - OCP를 위배한다.(OOP 설계 원칙)
    • 시스템이 커져서 확장 될 경우 연동되는 시스템에도 영향을 줄 수 있다.
  • 디자인 패턴으로 문제를 해결할 수 있다.
class VendingMachine {
	pay() {
    	console.log("cash pay!")
    }
}

위의 코드는 VendingMachine class 함수가 존재하고 pay 메서드 안에 "cash pay!"가 호출되게끔 구현되어있다.
만약 여기서 결제 방식이 cash가 아닌 card로 변경된다면, 메소드 내에 있는 코드 수정이 불가피해 보인다. 이는 OOP 설계 원칙 중 하나인 OCP(open close principle: 수정에는 닫혀있다는 원칙)를 위배하게 된다. 또한 시스템이 커져서 확장 될 경우 pay 메소드 안에 코드량이 증가하게 된다. 이는 내부 로직이 복잡해지게 되어 연동되는 시스템에도 영향을 끼칠 수 있는 요인이 된다.
따라서 이러한 문제를 해결하기 위해 전략패턴을 도입해 아래의 코드와 같이 해결할 수 있다.

interface PaymentStrategy {
 pay(): void;
}

class CardPaymentStrategy implements PaymentStrategy {
 pay(): void {
   console.log("card pay!");
 }
}

class CashPaymentStrategy implements PaymentStrategy {
 pay(): void {
   console.log("cash pay!");
 }
}

class VendingMachine {
 private paymentStrategy: PaymentStrategy;

 setPaymentStrategy(paymentStrategy: PaymentStrategy) {
   this.paymentStrategy = paymentStrategy;
 }

 pay() {
   this.paymentStrategy.pay();
 }
}

CardPaymentStrategyCashPaymentStrategy 두 클래스는 인터페이스 PaymentStrategy를 implements 했기 때문에 PaymentStrategy가 가지고 있는 pay() 메서드, 추상 메서드,를 각 클래스에서 구체화해야 한다. 그리고 VendingMachine 클래스에서 PaymentStrategy 변수를 선언해주고 외부에서 클래스 주입이 가능하도록 setPaymentStrategy함수를 구현한다. 그리고 최종적으로 VendingMachine 클래스에 pay() 메서드를 구현한 후에 pay() 메서드가 호출되었을 때, paymentStrategy.pay() 메서드가 호출되게끔 구현한다.
이렇게 하면 pay() 메서드가 호출되면 주입된 pay() 메서드의 strategy에 따라 다른 pay() 메서드가 호출된다.

const vendingMachine = new VendingMachine();

vendingMachine.setPaymentStrategy(new CashPaymentStrategy());
vendingMachine.pay(); // cash pay

vendingMachine.setPaymentStrategy(new CardPaymentStrategy());
vendingMachine.pay(); // card pay

위의 실행코드를 보면, vendingMachine 클래스를 생성하고 처음에 CashPaymentStrategy 클래스를 주입시킨다. 그리고 vendingMachine.pay() 메서드를 호출하게 되면, 'cash pay'가 콘솔에 찍히고 다시 CardPaymentStrategy 클래스를 주입시킨 후 아까와 같이 함수를 호출하면 'card pay'로 콘솔에 찍히는 것을 알 수 있다.

이렇게 전략패턴을 통해 메서드의 내부 로직을 수정할 필요 없이 전략을 바꿔 동적으로 행위의 수정을 할 수 있다.

0개의 댓글