# 상태 (State) 패턴

# 상태 패턴이란 무엇인가요?

TIP

객체 내부 상태 변경에 따라 객체의 행동이 달라지는 패턴.

  • 상태에 특화된 행동들을 분리해 낼 수 있으며, 새로운 행동을 추가하더라도 다른 행동에 영향을 주지 않는다.

image

  • State - Context가 변경될 수 있는 상태에 대한 공통된 인터페이스이며, 추상 클래스이든 인터페이스이든 추상체로서 반드시 존재해야 한다.
  • Context - 상태 변경이 이루어지는 객체, 고유한 정보를 담고 있을 수 있음.
  • ConcreteState - 상태에 따라 달라지는 operation을 정의

즉, 객체의 특정 상태를 클래스로 선언하고, 클래스에서는 해당 상태에서 할 수 있는 행위들을 메서드로 정의한다.

그리고 이러한 각 상태 클래스들을 인터페이스로 캡슐화하여, 클라이언트에서 인터페이스를 호출하는 방식을 말한다.

# 상태 패턴을 적용해보자.

  • 여기에 TV가 있는데, 리모콘의 전원버튼을 누르면 꺼져있는 상태에서는 켜지고, 켜져있는 상태에서는 꺼진다.
  • 즉, 상태에 따라 행동이 달라지는 간단한 예시로 볼 수 있다.
public class TV {
    private State powerState = State.OFF;

    public enum State {
        ON, OFF
    }

    public void powerPush() {
        if (powerState == State.ON) {
            System.out.println("전원 off");
            powerState = State.OFF;
        } else {
            System.out.println("전원 on");
            powerState = State.ON;
        }
    }
}

다음처럼 상태에 따른 분기문이 발생하게 되고, 이는 상태의 확장을 어렵게 만든다.

public interface PowerState {
    public void powerPush(TV tv);
}
  • 상태를 위한 인터페이스를 만든다.
public class Off implements PowerState {
    @Override
    public void powerPush(TV tv) {
        System.out.println("전원 on");
        tv.setPowerState(new ON());
    }
}
public class On implements PowerState {
    @Override
    public void powerPush(TV tv) {
        System.out.println("전원 off");
        tv.setPowerState(new OFF());
    }
}
public class TV {
    private PowerState powerState;

    public TV() {
        this.powerState = new Off();
    }

    public void setPowerState(PowerState powerState) {
        this.powerState = powerState;
    }

    public void powerPush() {
        powerState.powerPush();
    }
}

# 상태 패턴의 장점과 단점은?

장점

  • 상태에 따른 동작을 개별 클래스로 옮겨서 관리할 수 있다.
  • 기존의 특정 상태에 따른 동작을 변경하지 않고 새로운 상태에 다른 동작을 추가할 수 있다.
  • 코드 복잡도를 줄일 수 있다.

단점

  • 복잡도가 증가한다.

# 상태 패턴의 예시

  • 주로 비지니스 로직에서 작성되는 코드이기 때문에 실질적인 사용 예시는 자바 스프링에서 찾아보기 힘들다.
  • javax.faces.lifecycle.LifeCycle#execute()

# 출처

  • https://kingchan223.tistory.com/323
  • https://victorydntmd.tistory.com/294
  • https://stackoverflow.com/questions/1673841/examples-of-gof-design-patterns-in-javas-core-libraries/2707195#2707195