S E P H ' S

[행동 패턴] 상태(State) 패턴 본문

Programing & Coding/Design Pattern

[행동 패턴] 상태(State) 패턴

yoseph0310 2023. 3. 19. 16:16

상태(State) 패턴

상태 패턴이란?

객체지향 프로그래밍에 대해서 공부했거나 조금 알고 있는 분들이라면 객체가 '상태'에 따라서 행위를 다르게 한다는 것에 대해서는 어느정도 알고 있을 것이다.

 

키가 145cm인 사람.

키 제한이 150cm인 놀이기구.

 

놀이기구 캐스트가 있다고 생각해보자. 놀이기구 캐스트는 손님이 놀이기구를 탈 수 있는지 없는지를 안내하는 행동을 한다. 키가 145인 이 손님은 놀이기구를 탈 수 없다. 1년 후, 이 사람이 키가 커서 155cm가 되었다. 이제는 이 사람은 놀이기구를 탈 수 있다. 이처럼 이 캐스트는 손님의 키라는 상태 상태에 따라서 놀이기구를 탈 수 있는지 없는지를 판단하여 안내한다.

 

언제 사용할까?

 

  • 객체 내부의 상태에 따라 동작을 달리 해야할 때 사용함.

 

구조

 

  • Context : 객체의 상태를 정의하는 데 사용되는 메소드를 정의하는 인터페이스
  • State : 상타에 따른 동작을 정의하는 인터페이스
  • ConcreteState : State에서 정의된 메소드를 구현하는 클래스

 

장단점

 

장점

  • 하나의 객체에 대한 여러 동작을 구현해야할 때, 상태 객체만 수정하므로 동작의 추, 삭제 및 수정이 간단해진다.
  • 객체에 상태에 따른 조건문(if/else, swtich)가 줄어들어 코드가 간결해지고 가독성이 향상된다.

단점

  • 상태에 따른 조건문을 대신한 상태 객체가 증가하여 관리해야할 클래스의 수가 증가한다.

 

예시

 

코드 예시는 핸드폰의 알림을 소리, 진동, 무음모드에 따라서 알림음을 다르게 하는 것을 코드로 작성해보겠다.

 

public class AlertStateContext {
    private MobileAlertState currentState;

    public AlertStateContext() {
        currentState = new Sound();
    }

    public void setCurrentState(MobileAlertState currentState) {
        this.currentState = currentState;
    }

    public void alert() {
        currentState.alert(this);
    }
}

 

public interface MobileAlertState {
    public void alert(AlertStateContext ctx);
}

 

상태를 정의하는 Context와 Interface를 만든다. 그 다음 각 상태에 따라 다른 행동을 하는 클래스들을 만든다.

 

public class Sound implements MobileAlertState {

    @Override
    public void alert(AlertStateContext ctx) {
        System.out.println("Sound");
    }

}

 

public class Vibration implements MobileAlertState {
    @Override
    public void alert(AlertStateContext ctx) {
        System.out.println("Vibration");
    }
}

 

public class Silent implements MobileAlertState {
    @Override
    public void alert(AlertStateContext ctx) {
        System.out.println("Silent");
    }
}

 

 

테스트
public class StateTest {
    public static void main(String[] args) {
        AlertStateContext stateContext = new AlertStateContext();

        stateContext.alert();
        stateContext.setCurrentState(new Vibration());
        stateContext.alert();
        stateContext.setCurrentState(new Silent());
        stateContext.alert();

    }
}

기본 상태를 Sound로 주었기 때문에 가장 먼저 Sound가 출력되고 상태를 변경함에 따라 각각 Vibration, Silent를 출력하며 alert()라는 동일 메소드에 대해 다른 작동을 하는 것을 확인할 수 있다. 클래스를 통해서 가독성을 높일 수 있다는 장점과 그에 따라 관리해야할 클래스가 증가하면 불편해질 수 있다는 단점을 염두에 두고 코드를 작성해야 한다는 생각이 들었다. 만약 코드의 가독성을 중점으로 두는 집단이 있다면 생각해볼만한 패턴이라고 생각이 든다.