자바 디자인 패턴 용어 사전
행위 패턴전략 · 상태 패턴

Strategy

알고리즘을 캡슐화해 런타임에 교체하는 패턴. 조건 분기를 다형성으로 바꾼다.

알고리즘을 각각 클래스로 캡슐화해 런타임에 바꿔 끼우는 패턴.

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 이 가장 읽기 쉽다

함께 보면 좋은 용어

노트에서 맥락과 함께 보기 — 행위 패턴 ③ — 알고리즘과 상태를 갈아 끼운다