전략 패턴(Strategy Pattern)은 객체의 행위를 캡슐화하여, 런타임에 동적으로 교체할 수 있도록 하는 디자인 패턴입니다. 이 패턴을 사용하면 알고리즘을 정의하고, 이를 독립적인 전략 객체로 만들어 클라이언트 코드에서 쉽게 교체할 수 있습니다. 전략 패턴은 알고리즘을 클라이언트 코드와 분리하여, 유지보수성과 확장성을 향상시키는 데 유용합니다.
전략 패턴의 구성 요소
전략 패턴은 다음과 같은 주요 구성 요소로 이루어져 있습니다:
- Context (환경): 전략을 사용하는 클라이언트 클래스입니다. 클라이언트는
Strategy
객체를 사용하여 행동을 수행합니다.
- Strategy (전략): 알고리즘의 인터페이스를 정의하는 추상 클래스 또는 인터페이스입니다. 다양한 알고리즘을
Strategy
인터페이스를 구현하여 제공합니다.
- ConcreteStrategy (구체적인 전략):
Strategy
인터페이스를 구현하는 구체적인 알고리즘 클래스입니다. 서로 다른 알고리즘을 제공하여Context
에서 사용할 수 있습니다.
전략 패턴 예제
문제 설명: 예를 들어, 다양한 결제 방법을 제공하는 쇼핑몰이 있다고 가정해봅시다. 고객이 결제할 때 신용카드, 페이팔, 은행 송금 등 여러 가지 방법 중 하나를 선택할 수 있습니다. 전략 패턴을 사용하여 결제 방법을 교체할 수 있는 구조를 구현할 수 있습니다.
1. Strategy 인터페이스 정의
// 1. Strategy 인터페이스
public interface PaymentStrategy {
void pay(int amount);
}
2. ConcreteStrategy 클래스 정의
// 2. ConcreteStrategy: 신용카드 결제
public class CreditCardPayment implements PaymentStrategy {
private String cardNumber;
public CreditCardPayment(String cardNumber) {
this.cardNumber = cardNumber;
}
@Override
public void pay(int amount) {
System.out.println("신용카드 결제: " + amount + "원");
}
}
// 3. ConcreteStrategy: 페이팔 결제
public class PayPalPayment implements PaymentStrategy {
private String email;
public PayPalPayment(String email) {
this.email = email;
}
@Override
public void pay(int amount) {
System.out.println("페이팔 결제: " + amount + "원");
}
}
3. Context 클래스 정의
// 4. Context: 결제 처리기
public class PaymentProcessor {
private PaymentStrategy paymentStrategy;
public PaymentProcessor(PaymentStrategy paymentStrategy) {
this.paymentStrategy = paymentStrategy;
}
public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
this.paymentStrategy = paymentStrategy;
}
public void processPayment(int amount) {
paymentStrategy.pay(amount);
}
}
4. 사용 예제
// 5. 사용 예제
public class Main {
public static void main(String[] args) {
PaymentStrategy creditCardPayment = new CreditCardPayment("1234-5678-9876-5432");
PaymentStrategy paypalPayment = new PayPalPayment("user@example.com");
PaymentProcessor processor = new PaymentProcessor(creditCardPayment);
processor.processPayment(100); // 출력: 신용카드 결제: 100원
processor.setPaymentStrategy(paypalPayment);
processor.processPayment(200); // 출력: 페이팔 결제: 200원
}
}
전략 패턴의 장점
- 알고리즘 캡슐화: 각 알고리즘을 독립적으로 캡슐화하여,
Context
와 분리할 수 있습니다. 새로운 알고리즘을 추가할 때 기존 코드에 영향을 주지 않습니다.
- 동적 교체: 실행 중에 전략을 동적으로 변경할 수 있습니다. 예를 들어, 결제 방법을 사용자가 선택에 따라 쉽게 변경할 수 있습니다.
- 확장 용이: 새로운 전략을 추가하는 것이 용이하며, 기존 코드를 변경할 필요 없이 새로운 알고리즘을 추가할 수 있습니다.
- 유지보수성 향상: 알고리즘이 독립적으로 관리되므로, 코드의 유지보수성이 향상됩니다. 특정 전략의 수정이 다른 전략에 영향을 미치지 않습니다.
전략 패턴의 단점
- 클래스 수 증가: 각 알고리즘마다 별도의 클래스가 필요하므로 클래스 수가 증가할 수 있습니다.
- 복잡성 증가: 전략 패턴을 사용하는 경우, 전체 구조가 복잡해질 수 있으며, 이를 이해하고 관리하는 데 추가적인 노력이 필요할 수 있습니다.
결론
전략 패턴은 알고리즘을 캡슐화하고 동적으로 교체할 수 있도록 도와줍니다. 이 패턴을 사용하면 코드의 유지보수성과 확장성이 향상되며, 다양한 알고리즘을 손쉽게 추가하고 교체할 수 있습니다. 위의 예제와 설명을 통해 전략 패턴의 개념과 구현 방법을 이해하고, 실무에서 유용하게 활용할 수 있습니다.
Share article