✅ 전략 패턴이란?
- 기능을 캡슐화하여 동적으로 기능을 선택할 수 있게 해주는 디자인 패턴이다.
- 비슷한 작업을 수행하는 여러 기능이 있을 때, 이 기능들을 개별 클래스로 캡슐화하고, 실행 시점에 필요한 기능을 선택할 수 있도록 한다.
✅ 핵심 개념
- 캡슐화: 각 기능을 별도의 클래스로 분리
- 유연성: 실행 시점에 행위를 선택, 변경 가능
- 구성(Composition): 실행 클래스가 특정 기능을 직접 구현하지 않고, 해당 기능을 다른 클래스에서 위임 받아 실행
✅ 구조
- Context: 클라이언트가 사용하는 객체로 전략(기능)을 실행한다.
- Strategy: 기능을 정의하는 인터페이스
- ConcreteStrategy: Strategy를 구현하는 구체적인 기능 클래스
✅ 장단점
장점
- 개방-폐쇄 원칙(OCP) 준수: 기능을 추가하거나 변경해도 기존 코드에 영향을 미치지 않음
- 코드 재사용성 증가: 기능을 독립적인 클래스로 분리
- 유연성: 실행 시점에 전략을 쉽게 변경 가능
단점
- 구현 복잡성 증가: 간단한 작업에도 많은 클래스를 생성
- 추가 비용 발생: 객체를 생성하고 관리해야 하므로 약간의 성능 비용
✅ 예제 코드: 여러가지 결제 방식
- 결제 애플리케이션을 만든다고 가정
- 여러가지 결제 방식 중 하나를 결제 시점에 선택할 수 있어야 함
1️⃣ Strategy 인터페이스 정의
public interface PaymentStrategy {
void pay(int amount);
}
2️⃣ ConcreteStrategy 클래스 구현
// 신용카드
@RequiredArgsConstructor
public class CreditCardPayment implements PaymentStrategy {
private final String cardNumber;
@Override
public void pay(int amount) {
System.out.println(amount + "원을 신용카드(" + cardNumber + ")로 결제합니다.");
}
}
// 페이팔
@RequiredArgsConstructor
public class PayPalPayment implements PaymentStrategy {
private final String email;
@Override
public void pay(int amount) {
System.out.println(amount + "원을 PayPal 계정(" + email + ")으로 결제합니다.");
}
}
// 비트코인
@RequiredArgsConstructor
public class BitcoinPayment implements PaymentStrategy {
private final String walletId;
@Override
public void pay(int amount) {
System.out.println(amount + "원을 비트코인 지갑(" + walletId + ")으로 결제합니다.");
}
}
3️⃣ Context 클래스 정의
// 전략을 실제로 실행하는 context 클래스
@RequiredArgsConstructor
public class PaymentContext {
private final PaymentStrategy strategy;
// 결제 수행
public void pay(int amount) {
strategy.pay(amount);
}
}
4️⃣ 사용 예시 및 결과
public class AppMain {
public static void main(String[] args) {
CreditCardPayment creditCardPayment = new CreditCardPayment("1234-5678-9012-3456");
PaymentContext context1 = new PaymentContext(creditCardPayment);
context1.pay(10000);
PayPalPayment payPalPayment = new PayPalPayment("user@example.com");
PaymentContext context2 = new PaymentContext(payPalPayment);
context2.pay(20000);
BitcoinPayment bitcoinPayment = new BitcoinPayment("bitcoin id");
PaymentContext context3 = new PaymentContext(bitcoinPayment);
context3.pay(30000);
}
}
10000원을 신용카드(1234-5678-9012-3456)로 결제합니다.
20000원을 PayPal 계정(user@example.com)으로 결제합니다.
30000원을 비트코인 지갑(bitcoin id)으로 결제합니다.
이처럼 전략 패턴을 사용하면 다양한 알고리즘을 독립적으로 관리하고, 실행 시점에 동적으로 사용할 수 있다. 특히 확장성과 유연성이 중요한 프로젝트에서 유용하게 사용된다.