전략 패턴(Strategy Pattern)은 "전략"이라고 부르는 알고리즘을 캡슐화하여,
컨텍스트(Context) 안에서 서로 교체할 수 있게 만드는 디자인 패턴입니다.
즉, 하나의 기능(예: 로그인, 결제 등)을 다양한 방법으로 구현할 수 있고,
이 방법들을 쉽게 갈아끼울 수 있도록 설계합니다.
전략 패턴을 적용하면 다음과 같은 장점이 있습니다.
예를 들어, 사용자가 로그인할 때 다음과 같은 전략을 선택할 수 있습니다.
또는 결제할 때 다음과 같은 전략을 사용할 수 있습니다.
Node.js의 유명한 인증 라이브러리인 passport도 전략 패턴을 기반으로 설계되어 있습니다.
여러 인증 전략(passport-kakao, passport-google 등)을 쉽게 추가하고 교체할 수 있습니다.
아래는 쇼핑몰 결제 시스템을 전략 패턴으로 구현한 예시입니다.
interface PaymentStrategy {
void pay(int amount);
}
class KakaoCardStrategy implements PaymentStrategy {
private final String name;
private final String cardNumber;
private final String cvv;
private final String dateOfExpiry;
public KakaoCardStrategy(String name, String cardNumber, String cvv, String dateOfExpiry) {
this.name = name;
this.cardNumber = cardNumber;
this.cvv = cvv;
this.dateOfExpiry = dateOfExpiry;
}
@Override
public void pay(int amount) {
System.out.println(amount + "원을 KakaoCard로 결제합니다.");
}
}
class LunaCardStrategy implements PaymentStrategy {
private final String emailId;
private final String password;
public LunaCardStrategy(String emailId, String password) {
this.emailId = emailId;
this.password = password;
}
@Override
public void pay(int amount) {
System.out.println(amount + "원을 LunaCard로 결제합니다.");
}
}
import java.util.ArrayList;
import java.util.List;
class Item {
private final String name;
private final int price;
public Item(String name, int cost) {
this.name = name;
this.price = cost;
}
public int getPrice() {
return price;
}
}
class ShoppingCart {
private final List<Item> items = new ArrayList<>();
public void addItem(Item item) {
items.add(item);
}
public void removeItem(Item item) {
items.remove(item);
}
public int calculateTotal() {
return items.stream().mapToInt(Item::getPrice).sum();
}
public void pay(PaymentStrategy paymentMethod) {
int amount = calculateTotal();
paymentMethod.pay(amount);
}
}
public class Main {
public static void main(String[] args) {
ShoppingCart cart = new ShoppingCart();
Item item1 = new Item("노트북", 2000000);
Item item2 = new Item("마우스", 50000);
cart.addItem(item1);
cart.addItem(item2);
// KakaoCard로 결제
PaymentStrategy kakaoPay = new KakaoCardStrategy("홍길동", "1234-5678-9012-3456", "123", "12/25");
cart.pay(kakaoPay);
// LunaCard로 결제
PaymentStrategy lunaPay = new LunaCardStrategy("user@example.com", "securepassword");
cart.pay(lunaPay);
}
}
2050000원을 KakaoCard로 결제합니다.
2050000원을 LunaCard로 결제합니다.
디자인 패턴을 공부하다 보면 "왜 이렇게 복잡하게 만들지?"라고 생각할 때가 있습니다.
하지만 실제 서비스가 커지고 기능이 추가될수록,
전략 패턴 같은 유연한 설계가 얼마나 중요한지 몸소 느끼게 됩니다.
기억해야 할 핵심은 다음과 같습니다:
"변화에 유연하게 대응할 수 있도록 미리 준비하는 것"
그게 바로 좋은 설계입니다.