학습 목표

  • 객체의 상태에 따라 동작이 달라지는 구조를 설계하는 방법 학습
  • if-else/Switch 지옥 제거 → 상태 확장이 쉬운 구조 만들기
  • 객체지향 원칙(SOLID) 중 OCP(개방-폐쇄 원칙) 실천

상황 예제

  • “문(door)” 상태 제어

예제

더보기

문에 열리는 상태에 따라 이전 상태를 가지고 변환하는 로직

  • State 인터페이스
public interface DoorState {
    void open(Door door);
    void close(Door door);
    void lock(Door door);
}
  • Context — Door
public class Door {
    private DoorState state;

    public Door() {
        this.state = new ClosedState(); // 초기 상태
    }

    public void setState(DoorState state) {
        this.state = state;
    }

    public void open() {
        state.open(this);
    }

    public void close() {
        state.close(this);
    }

    public void lock() {
        state.lock(this);
    }
}
  • 구체적인 상태 객체
public class ClosedState implements DoorState {

    @Override
    public void open(Door door) {
        System.out.println("문이 열렸습니다.");
        door.setState(new OpenedState());
    }

    @Override
    public void close(Door door) {
        System.out.println("이미 닫혀 있습니다.");
    }

    @Override
    public void lock(Door door) {
        System.out.println("문을 잠궜습니다.");
        door.setState(new LockedState());
    }
}


public class LockedState implements DoorState {

    @Override
    public void open(Door door) {
        System.out.println("문이 잠겨 있어 열 수 없습니다!");
    }

    @Override
    public void close(Door door) {
        System.out.println("이미 닫혀 있습니다.");
    }

    @Override
    public void lock(Door door) {
        System.out.println("이미 잠긴 상태입니다.");
    }
}

public class OpenedState implements DoorState {

    @Override
    public void open(Door door) {
        System.out.println("이미 열려 있습니다.");
    }

    @Override
    public void close(Door door) {
        System.out.println("문을 닫았습니다.");
        door.setState(new ClosedState());
    }

    @Override
    public void lock(Door door) {
        System.out.println("문이 열려 있어 잠글 수 없습니다!");
    }
}
  • 실행
public class StatePatternExample {
    public static void main(String[] args) {
        Door door = new Door();

        door.lock();
        door.open();
        door.close();
        door.lock();
        door.open();
    }
}

- 생성자에서 처음 초기 값을 ClosedState 상태로 초기화한 상태에서 문을 잠그면, LockedState 상태로 변경되고 해당 상태에서는 열고, 닫고, 잠그는 행동을 하지 못하는 것을 볼 수 있다. 전략 패턴에서 함수를 바꾸었다면 해당 예제는 상태 자체를 바꾸는 느낌에 패턴

 

마무리

SOLID에서 OCP예제 중에서 대표적인 예제가 아닌가 생각이 듭니다. if / else 지옥으로 만들었을 문제를 현제 상태를 가지고 현재 내가 할 수 있는 행동을 만들 때 쓰인 개념 같습니다.

+ Recent posts