행동 (3) - 상태(State) 패턴
- 객체의 상태에 따라 처리를 다르게 하는 패턴
 - 상태 패턴을 사용하면 상태에 따라 캡슐화 된 다른 클래스를 사용하기 때문에 객체의 클래스가 바뀌는 것과 같은 결과를 얻을 수 있다
 
용어

- State : 상태 인터페이스
 - Concrete State : 각 상태에 따른 처리 클래스
 - Context : State를 사용하는 객체
 
구현
- State
    
- 상태를 별도의 클래스로 캡슐화
 
 
public interface ElevatorState {
    public void pushUpButton();
    public void pushDownButton();
    public void pushStopButton();
}
- Concrete State
 
public class UpState implements ElevatorState {
    @Override
    public void pushUpButton() {
        System.out.println("XXX");
    }
    @Override
    public void pushDownButton() {
        System.out.println("Down!!");
    }
    @Override
    public void pushStopButton() {
        System.out.println("Stop!!");
    }
}
public class DownState implements ElevatorState {
    @Override
    public void pushUpButton() {
        System.out.println("Up!!");
    }
    @Override
    public void pushDownButton() {
        System.out.println("XXX");
    }
    @Override
    public void pushStopButton() {
        System.out.println("Stop!!");
    }
}
public class StopState implements ElevatorState {
    @Override
    public void pushUpButton() {
        System.out.println("Up!!");
    }
    @Override
    public void pushDownButton() {
        System.out.println("Down!!");
    }
    @Override
    public void pushStopButton() {
        System.out.println("XXX");
    }
}
- Context
    
- 클라이언트로 부터 실행을 요청 받고 상태 객체에 처리를 위임한다
 - 요청을 처리하고 상태를 변경시킨다
 
 
public class Elevator {
    private ElevatorState elevatorState;
    public Elevator() {
        elevatorState = new StopState();
    }
    private void setState(ElevatorState state) {
        this.elevatorState = state;
    }
    public void pushUpButton() {
        elevatorState.pushUpButton();
        setState(new UpState());
    }
    public void pushDownButton() {
        elevatorState.pushDownButton();
        setState(new DownState());
    }
    public void pushStopButton() {
        elevatorState.pushStopButton();
        setState(new StopState());
    }
}
- Client
 
public class Main {
    public static void main(String[] args) {
        Elevator elevator = new Elevator();
        elevator.pushUpButton();
    }
}
장점
- 상태에 따른 동작을 개별 클래스로 옮겨 관리할 수 있다
 - 기존의 특정 상태에 따른 동작을 변경하지 않고 새로운 상태에 다른 동작을 추가할 수 있다 [OCP]
 
단점
- 복잡도가 증가한다
 
상태 패턴 vs 전략 패턴
- 상태
    
- 상황에 따라 여러 상태 객체 중 한 객체에게 모든 행동을 맡겨 자연스럽게 객체가 바뀐다
 - 클라이언트는 상태 객체를 몰라도 된다
 
 - 전략
    
- 클라이언트가 Context 객체에세 어떤 전략 객체를 사용할지 지정해준다