자바 디자인 패턴 용어 사전
행위 패턴상태 기계

State

상태를 객체로 만들어 행동을 바꾸는 패턴. 상태 전이 규칙을 각 상태가 갖는다.

상태를 객체로 만들어, 상태가 바뀌면 객체의 행동이 통째로 바뀌게 하는 패턴.

무엇을 푸는가 — 조건문 폭발

// Before — 상태가 늘 때마다 모든 메서드를 고쳐야 한다
void publish() {
    if (state == DRAFT)        { state = MODERATION; }
    else if (state == MODERATION) { if (isAdmin) state = PUBLISHED; }
    else if (state == PUBLISHED)  { /* 아무것도 안 함 */ }
}
void render() { if (state == DRAFT) ... else if ... }   // 같은 분기가 반복된다
// After — 상태마다 클래스
interface State { void publish(Document doc); }

class Draft implements State {
    public void publish(Document d) { d.setState(new Moderation()); }
}
class Moderation implements State {
    public void publish(Document d) { if (d.isAdmin()) d.setState(new Published()); }
}
class Published implements State {
    public void publish(Document d) { /* 최종 상태 */ }
}

class Document {
    private State state = new Draft();
    void publish() { state.publish(this); }     // 분기가 사라진다
}

Strategy와의 차이 (★ 가장 많이 묻는다)

구조는 거의 같다 — 인터페이스 + 여러 구현 + 위임 다른 것은 '누가 바꾸고, 서로를 아는가' 다

  • Strategy — 클라이언트가 밖에서 골라 넣는다

    • 전략끼리 서로를 모른다 (독립적·대체 가능)
    • "어떻게 할지" 를 고른다 — 정렬 알고리즘, 결제 수단
  • State — 객체가 스스로 다음 상태로 바꾼다

    • 상태끼리 전이 관계를 안다 (Draft 는 다음이 Moderation 임을 안다)
    • "지금 무엇인지" 에 따라 행동이 달라진다 — 주문 상태, 문서 워크플로

대가

  • 상태가 적고 전이가 단순하면 클래스만 늘어난다 (enum + switch 로 충분)
  • 전이 규칙이 각 상태에 흩어져 전체 흐름을 한눈에 보기 어렵다
    • 전이표를 문서나 다이어그램으로 따로 유지하는 것이 좋다

실무에서

주문 상태 (결제대기 → 결제완료 → 배송중 → 배송완료 → 취소/반품) 문서 워크플로 (초안 → 검토 → 승인 → 게시) TCP 연결 상태 · Spring StateMachine

면접 함정

  • "Strategy와 같다" → 구조가 같아도 누가 전환하는가가 다르다.
  • 상태 2개짜리에 도입boolean이나 enum이 더 읽기 쉽다.

전이를 어디에 둘 것인가

  • 방식 A — 각 상태가 다음 상태를 안다

    • 장점 상태별 규칙이 응집된다 / 단점 전체 전이도를 한눈에 못 본다
  • 방식 B — 컨텍스트나 전이표가 규칙을 갖는다

    • 장점 전이 전체가 한 곳에 보인다 / 단점 상태가 늘면 표가 커진다
  • 실무에서는 전이도를 문서로 유지하며 A 를 쓰는 경우가 많다

enum으로도 만들 수 있다

enum OrderState {
    PAID     { OrderState next() { return SHIPPING; } },
    SHIPPING { OrderState next() { return DELIVERED; } },
    DELIVERED{ OrderState next() { return this; } };
    abstract OrderState next();
}

상태가 고정이고 상태별 데이터가 없으면 enum이 간결하다. 상태마다 필드·의존성이 필요하면 클래스로 간다.

상태를 어디에 저장하나

DB 에는 상태 '이름'(문자열·코드) 을 저장하고 로드 시 State 객체로 복원한다

이때 저장된 상태 값이 곧 외부 계약이 된다

  • 상태 이름을 바꾸면 마이그레이션이 필요하다

함께 보면 좋은 용어

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