본문 바로가기
학습/Spring

[spring] Spring State Machine

by KKambi 2020. 10. 31.

스테이트 머신(상태 기계)를 이해하기 위해서는 먼저 오토마타 이론을 간략하게 이해해야 한다.

컴퓨터 공학 수업에선 오토마타를 배운다는데... 나는 컴공이 아니기 때문에 ㅠ_ㅠ

위키피디아에 검색하면 자세하게 학습할 수 있다.

 

 

오토마타 이론

계산 능력이 있는 추상 기계와 그 기계를 이용해서 풀 수 있는 문제를 연구하는 컴퓨터 과학 분야

  • 추상 기계 = 오토마타라고 지칭
  • 오토마타는 일반적으로 유한한 상태를 가지며, 입력을 받아 일정하게 상태를 전이하며, 출력을 내놓는다.

 

 

유한 상태 기계

유한한 개수의 상태를 가질 수 있는 오토마타

  • 한 번에 오로지 1개의 상태만을 가진다.
  • 현재 상태(Current State) = 임의의 주어진 시간에 기계가 갖고 있는 상태
  • 어떤 사건(Event)에 의해 한 상태에서 다른 상태로 변화할 수 있으며, 이를 전이(Transition)이라 한다.
  • 특정한 유한 기계 = 현재 상태로부터 가능한 전이 상태 + 전이를 유발하는 조건들의 집합으로 정의

 

Spring State Machine

오토마타 기반 프로그래밍

  • 프로그램 또는 그 일부가 유한 상태 기계(FSM, Finite State Machine)의 모델로 간주되는 프로그래밍 패러다임
  • Event-Driven 프로그래밍과 유사
    • 이벤트 드리븐 : 이벤트 리스너를 미리 등록 - 이벤트 발생 - 리스너의 정해진 행동 수행
    • 스테이트 머신 : 상태가 변화될 수 있는 규칙을 미리 등록 - 이벤트 발생 - 상태 전이

 

상태 시스템을 사용하기 좋은 상황

  • 어프리케이션 혹은 그 구조의 일부를 상태로 표현할 때
  • 복잡한 로직을, 더 작고 관리할 수 있는 단위로 쪼개고 싶을 때
  • 비동기 요청 등에서 동시성 문제를 겪을 때

 

전반적인 사용법

  • Enum으로 가능한 상태 및 발생할 수 있는 이벤트를 정의하고, 필요한 메소드를 구현한다.
    별도의 클래스로 두면 관리하기 편하다.
  • EnumStateMachineConfigurerAdapter를 상속한 클래스를 구현한다.
    1. StateMachineStateConfigurer를 인자로 받는 메소드에서 상태 관련 설정을 구현한다.
    - 초기 시작 상태
    - 전이될 수 있는 다른 상태값
    - 종료값 등
    2. StateMachineTransitionConfigurer를 인자로 받는 메소드에서 전이 관련 설정을 구현한다.
    - 현재 상태 (Source)
    - 전이 상태 (Target)
    - 이벤트 (Event)
    - 어떤 소스에서, 어떤 타겟으로, 어떤 이벤트에 의해, 어떤 액션을 취하면서 전이되는지?

 

★주의★ 예제 코드

  • 상용 환경에서 테스트해본 코드가 아니므로 정상 작동하지 않을 것이다.
  • 아래의 짧은 설정은 빙산의 일각이다. 실제로는 다양한 메소드를 사용할 수 있다.
  • 이런 원리로 작동한다는 개념만 알고 갔으면 좋겠다.
// 상태, 이벤트를 정의하는 클래스
public class StateManager {
	
    private StateManager() {
    	throw new AssertionError();
    }
    
    public enum BookStates {
    	OWNED,
        RENTAL,
        LOST;
    }
    
    public enum BookEvents {
    	RentEvent,
        ReturnEvent,
        LoseEvent;
    }

    public static List<BookStates> get
}

// 유한 상태 기계를 정의하는 클래스
@Configuration
@EnableStateMachineFactory
@RequiredArgsConstructor
public class StateManagerConfigure extends StateMachineConfigurerAdapter<StateManager.BookStates, StateManager.BookEvents> {

    private final StateManagerConfigurerService stateManagerConfigurerService;

    @Override
    public void configure(StateMachineStateConfigurer<StateManager.CreativeStates, StateManager.CreativeEvents> states) throws Exception {

        states.withStates()
                .initial(StateManager.BookStates.OWNED)
                .state(StateManager.BookStates.RENTAL)
                .state(StateManager.BookStates.LOST);
    }

    @Override
    public void configure(StateMachineTransitionConfigurer<StateManager.CreativeStates, StateManager.CreativeEvents> transitions) throws Exception {

        transitions
                .withExternal()
                    .sourceStateManager.BookStates.OWNED)
                    .target(StateManager.BookStates.RENTAL)
                    .event(StateManager.BookEvents.RentEvent)
                    .and()
                .withExternal()
                    .source(StateManager.BookStates.OWNED)
                    .target(StateManager.BookStates.LOST)
                    .event(StateManager.BookEvents.LoseEvent)
                    .and()
                .withExternal()
                    .source(StateManager.BookStates.RENTAL)
                    .target(StateManager.BookStates.OWNED)
                    .event(StateManager.BookEvents.ReturnEvent)
                    .and()
        ;

    }
}

 

 

 

 

 

참고

plateer 위키 페이지 (한글)

코드버스트 스테이트 머신 설명 (영어)

위키피디아 오토마타 이론 (한글)

 

회사에서 사용하는 스프링 스테이트 머신을 이해하기 위해, 위의 링크들을 많이 참고했다.

스프링 서브 프로젝트라고는 하지만 사용하는 곳이 별로 없는 건지

한글 포스팅도 많이 없고 답답한 마음에 직접 작성했다.

다음 이터레이션에서 적용하게 된다면, 예제 코드를 더욱 보강해야겠다.

 

그리고 plateer wiki 페이지는 어제까지만 해도 잘 사용했는데 무슨 일인지 오늘은 404 에러가 뜬다....

 

댓글