알고리즘을 각각 클래스로 캡슐화해 런타임에 바꿔 끼우는 패턴.
interface SortStrategy { void sort(int[] a); }
class QuickSort implements SortStrategy { ... }
class MergeSort implements SortStrategy { ... }
class Sorter {
private SortStrategy strategy;
void setStrategy(SortStrategy s) { this.strategy = s; } // 런타임 교체
void sort(int[] a) { strategy.sort(a); }
}
무엇을 없애나 — 조건 분기
// ❌ 새 방식이 늘 때마다 이 메서드를 고친다 (OCP 위반)
void calculate(String type) {
if (type.equals("fixed")) { ... }
else if (type.equals("rate")) { ... }
}
// ✅ 새 전략 클래스를 '추가' 하면 끝난다
Strategy는 OCP를 가장 직접적으로 구현한 패턴이다.
함수형 언어에서는 함수 하나면 된다
// 인터페이스와 클래스 없이 람다로
void process(List<Item> items, Comparator<Item> order) { items.sort(order); }
process(items, Comparator.comparing(Item::price));
"메서드가 하나뿐인 전략 인터페이스"는 대개 함수 타입으로 대체된다 — 패턴이 언어 기능에 흡수된 사례다.
State와 무엇이 다른가 — 가장 자주 나오는 비교
-
구조는 거의 같다. 의도가 다르다
-
Strategy — '어떻게 할지' 를 고른다
- 클라이언트가 전략을 정해 주입한다
- 전략끼리 서로를 모른다
-
State — '지금 어떤 상태인지' 에 따라 동작이 달라진다
- 상태 객체가 스스로 다음 상태로 전이시킨다
- 상태끼리 서로를 안다 (전이 규칙)
// State — 상태가 스스로 전이한다
interface OrderState { void next(Order o); }
class Paid implements OrderState {
public void next(Order o) { o.setState(new Shipped()); } // 다음 상태를 안다
}
"전이를 누가 아는가" 가 판별 기준이다 — 클라이언트가 정하면 Strategy, 객체가 스스로 바꾸면 State다.
실무에서의 형태
// 전략을 맵으로 등록해 두고 고른다 (if-else 제거의 실전 형태)
Map<PayType, PayMethod> methods = Map.of(
PayType.CARD, new CardPay(),
PayType.BANK, new BankPay()
);
methods.get(type).pay(amount);
면접 함정
- ❌ "Strategy와 State는 다른 구조" → 구조는 사실상 같다. 의도와 전이 주체가 다르다.
- ❌ "if-else는 무조건 Strategy로" → 분기가 두세 개이고 늘지 않으면 그냥 두는 게 낫다.
전략을 어떻게 고르나
// ① 클라이언트가 직접 주입한다 (가장 단순)
new Sorter(new QuickSort());
// ② 조건에 따라 팩토리가 고른다
strategyFactory.get(dataSize > 10000 ? BIG : SMALL);
// ③ 전략 자신이 적용 가능 여부를 안다 (자주 쓰는 형태)
interface Handler {
boolean supports(Request r);
void handle(Request r);
}
handlers.stream().filter(h -> h.supports(req)).findFirst().orElseThrow().handle(req);
③이 실무에서 가장 유연하다 — 새 핸들러를 추가할 때 어느 곳도 고칠 필요가 없다.
상태를 어떻게 넘기나
-
전략이 컨텍스트의 데이터를 필요로 할 때
-
① 메서드 인자로 넘긴다 — → 전략이 무상태로 유지된다 (권장)
-
② 컨텍스트 자신을 넘긴다 — → 유연하지만 결합이 는다
-
③ 전략이 생성자로 받아 둔다 — → 전략이 상태를 가져 재사용이 어려워진다
-
무상태 전략은 싱글톤으로 공유할 수 있다는 이점이 있다
State의 전이를 어디에 두나
-
전이 규칙을 상태 객체 안에 두면 — 응집도는 높지만 상태끼리 서로를 안다
-
전이 테이블을 밖에 두면 — 상태는 독립적이지만 규칙이 흩어진다
-
상태가 적으면 enum + when 이 가장 읽기 쉽다