1. 개념 정리
전략 패턴(Strategy Pattern)은 실행할 수 있는 여러 알고리즘(전략) 중 하나를 상황에 따라 선택해서 사용할 수 있도록 만드는 디자인 패턴입니다.
쉽게 말해 “상황에 따라 다른 방식으로 처리하고 싶을 때, 그 방법들을 미리 정의해놓고 필요한 것만 골라 쓰는 구조”라고 보면 됩니다.
예를 들어 쇼핑몰에서 가격을 계산하는 방식이 여러 개 있다고 가정해봅시다.
- 일반 계산 방식
- 할인 쿠폰을 적용한 계산
- 멤버십 등급에 따라 포인트를 반영한 계산
이럴 때 전략 패턴을 사용하면 계산 로직들을 미리 전략으로 분리하고,
사용할 때마다 원하는 전략을 선택해서 주입할 수 있게 됩니다.
자바스크립트에서는 함수도 값처럼 다룰 수 있기 때문에, 전략을 함수로 정의해서 객체나 클래스에 전달하면 쉽게 구현할 수 있습니다!
2. 예제 코드
1) 전략을 함수로 분리한 기본 구조
// 전략 함수들 정의
function normalPricing(price) {
return price;
}
function discountPricing(price) {
return price * 0.9; // 10% 할인
}
function vipPricing(price) {
return price * 0.8; // 20% 할인
}
// 전략을 주입받는 컨텍스트
function calculatePrice(price, strategy) {
return strategy(price);
}
// 사용 예
console.log(calculatePrice(10000, normalPricing)); // 10000
console.log(calculatePrice(10000, discountPricing)); // 9000
console.log(calculatePrice(10000, vipPricing)); // 8000
가격 계산 방식은 3가지로 나뉘고, 각각 별도의 함수로 정의됩니다.
calculatePrice()
는 실제로 가격을 계산하는 함수인데, 어떤 방식으로 계산할지는 외부에서 결정합니다.
이 구조 덕분에 계산 전략을 쉽게 교체하거나 테스트할 수 있고, 로직이 변경돼도 calculatePrice()
는 건드릴 필요가 없습니다.
3. 언제 사용하면 좋을까?
1) 다양한 조건에 따라 처리 로직이 바뀌는 경우
예시 상황:
로그인한 사용자의 등급에 따라 결제 할인률이 다르게 적용되는 쇼핑몰
예시 코드:
const pricingStrategies = {
normal: price => price,
silver: price => price * 0.95,
gold: price => price * 0.9
};
function calculate(price, level) {
const strategy = pricingStrategies[level] || pricingStrategies['normal'];
return strategy(price);
}
고객 등급이 늘어나더라도 전략만 추가하면 되고, 가격 계산 함수는 바뀌지 않으니 유지보수가 매우 쉬워집니다.
2) 조건문이 많아지는 걸 피하고 싶을 때
예시 상황:
결제 수단(PayPal, 카드, 포인트 등)에 따라 다른 결제 로직을 적용해야 할 때
예시 코드:
const payStrategies = {
card: amount => `카드로 ${amount}원 결제 완료`,
paypal: amount => `PayPal로 ${amount}원 결제 완료`,
point: amount => `포인트로 ${amount}원 결제 완료`
};
function processPayment(amount, method) {
const pay = payStrategies[method];
if (!pay) throw new Error("지원하지 않는 결제 수단입니다.");
return pay(amount);
}
console.log(processPayment(10000, 'card')); // 카드로 10000원 결제 완료
결제 수단이 추가되어도 새로운 전략만 추가하면 됩니다. if-else나 switch 문 없이도 깨끗하고 직관적인 코드를 유지할 수 있습니다.
4. 주의사항 (문제와 해결 방법)
1) 전략의 갯수가 너무 많아질 수 있음
- 전략이 많아지면 어떤 전략이 어디에 쓰이는지 추적이 어려워질 수 있습니다.
예시 상황:
결제 방식이 계속 늘어나는 쇼핑몰에서 어떤 전략이 어디서 사용되는지 추적하기 어려움.
개선 코드 예시:
// 각 전략을 별도 모듈로 분리 (예: paymentStrategies/card.js 등)
// strategies/index.js
const card = require('./card');
const paypal = require('./paypal');
const point = require('./point');
module.exports = {
card,
paypal,
point,
};
해결 방법:
- 전략을 파일 단위로 분리해서 유지보수성을 높이고,
- 문서화와 주석으로 전략의 역할을 명확히 정리하기
2) 전략이 너무 단순하면 오히려 복잡해질 수 있음
- 전략이 단순한 경우(예:
x * 0.9
)라면 오히려 따로 분리하는 게 번거로울 수 있습니다.
예시 상황:
// 너무 단순한 전략의 경우
const strategy = price => price * 0.9; // 너무 간단한 계산
// 불필요하게 함수로 분리하면 오히려 코드량만 증가
function discountStrategy(price) {
return price * 0.9;
}
해결 방법:
- 전략 패턴은 조건 분기와 확장성이 많을 때 유리하므로, 전략 개수가 충분하거나 자주 바뀔 때만 적용하기
- 단순한 연산이라면 굳이 전략 함수로 만들지 않아도 괜찮
정리 요약
- 전략 패턴은 여러 실행 방식 중 하나를 선택적으로 사용할 수 있게 해줍니다.
- 조건문 대신 전략 객체를 이용하면 더 깔끔한 코드가 됩니다.
- 자바스크립트에서는 함수도 값으로 쓸 수 있기 때문에 전략 패턴이 구현하기 쉬운 구조입니다.
- 단, 전략이 너무 단순하거나 너무 많으면 오히려 복잡해질 수 있으므로 구조와 문서화를 잘 해야 합니다.
'BE 공부 > 클린 코드' 카테고리의 다른 글
[디자인 패턴 입문] Decorator(데코레이터 패턴) (0) | 2025.07.07 |
---|---|
[디자인 패턴 입문] Observer(옵저버 패턴) (6) | 2025.07.04 |
[디자인 패턴 입문] Factory(팩토리 패턴) (2) | 2025.07.02 |
[디자인 패턴 입문] Singleton(싱글턴) (4) | 2025.07.02 |
[소프트웨어 설계] SOLID 원칙 (2) | 2025.07.01 |
댓글