본문 바로가기
Concepts/UML

UML - 상태 기계 다이어그램 - 구현

by ocwokocw 2021. 2. 12.

- 이 글은 UML Distilled (마틴 파울러)책을 기반으로 작성하였습니다.

- 상태 다이어그램의 구현

상태 다이어그램을 구현하는 방법은 크게 내장 스위치, 상태 패턴, 상태 표 세 가지가 있다. 상태 기계 다이어그램 가장 초반에 그린 아래 다이어그램을 가지고 각 방식으로 구현한 예제를 살펴보도록 하자.


- 내장 스위치

가장 직접적이고 간단한 방법이다. 하지만 간단한 상태 다이어그램도 이 방식으로 구현하면 장황해지는 단점이 있다.

 

public enum PanelState {
	WAIT, OPEN, LOCKED, FINAL
}

public enum PanelEvent {
	CANDLE_MOVED, KEY_TURNED, SELF_CLOSED
}

public class StateController {

	private PanelState currentState;
	
	private boolean isDoorClosed;
	private boolean isCandleIn;
	
	private void revealLock() {}
	private void openSafe() {}
	private void releaseMonster() {}

	public void handleEvent (PanelEvent panelEvent) {
		
		switch(currentState) {
			case WAIT:
				switch(panelEvent) {
					case CANDLE_MOVED:
						if(isDoorClosed) {
							revealLock();
							currentState = PanelState.LOCKED;
						}
					break;
				}
			break;
			case LOCKED:
				switch(panelEvent) {
					case KEY_TURNED:
						if(isCandleIn) {
							openSafe();
							currentState = PanelState.OPEN;
						}
						else {
							releaseMonster();
							currentState = PanelState.FINAL;
						}
					break;
				}
			break;
			case OPEN:
				switch(panelEvent) {
					case SELF_CLOSED:
						currentState = PanelState.WAIT;
					break;
				}
			break;
		}
		
	}
}

 

위 처럼 enum 으로 각각 상태와 이벤트를 정의한다. 가드 조건은 boolean 변수가 되고, 액티비티는 오퍼레이션이 된다. 전체적인 흐름은 switch(상태) 내에서 switch(이벤트) 가 발생하면 가드 일때 액티비티 수행 후 다음 상태를 할당하는 패턴이다.

 

사실 위와 같은 절차형은 직관적이고 구현이 쉽다는 장점이 있긴 하지만 코드가 너무 장황하고, 하나의 클래스내에서 모든 상태를 관할하므로 상태 다이어그램이 조금만 더 복잡해져도 읽기가 수월하지 않다.


- 상태 패턴

상태의 행동을 다루기 위해 상태 클래스의 계층 구조를 만들어내는 패턴이다. 다이어 그램에서 각 상태는 하나의 하위 클래스를 갖는다.

계층 구조 맨 위에는 Secret Panel State 클래스가 있고 이는 아무것도 하지 않는 이벤트 처리 메소드를 구현하는 추상 클래스이다. 하위의 대기 상태, 잠김 상태, 열림 상태는 해당 상태에서 가질 수 있는 전이에 대해 이벤트 메소드를 재정의 한다.


- 상태 표

상태 표는 상태 다이어그램 정보를 데이터의 관점에서 바라본다. 아래 표처럼 만들면 이를 해석하는 인터프리터를 만들거나 별도의 코드 생성기를 사용한다.

상태 표를 한번 더 만들어야 하는것은 번거롭지만 데이터의 관점에서 바라보기때문에 데이터만 잘 정의해 놓는다면 상태 다이어그램이 변경되어도 런타임에 변경가능하다.


- 상태 다이어그램을 언제 사용하는가?

상태 다이어그램은 객체 하나의 상태를 보는것이다. 그래서 유스 케이스가 여러개라도 중요한 객체 하나의 상태를 모니터링 하고자 할 때 사용한다. 만약 여러 객체들이 협력하는 행동을 보고자 한다면 상태 다이어그램을 사용하는것은 좋지 않은 선택이다.

 

상태 다이어그램을 사용할 때 시스템의 모든 클래스의 상태를 보겠다고 그리려고 하면 안된다. 이는 명백히 시간낭비 이며 복잡하거나 중요한 객체에 대한 동작을 이해하고자 할 때만 사용하는것이 좋다.

댓글