State Machine은 간단하게 정리하자면 상태를 가지고 있는 추상기계이다. 유한한 상태를 가진 기계를 Finite State Machine(FSM)이라고 한다. 임의의 주어진 시간동안에 상태를 현재상태(Current State)로 정의하고 어떠한 사건(Event)에 의해 상태가 변경될 수 있다. 이를 천이(transition)라고 부른다. transition으로 변경될 수 있는 상태와 변경 요인들의 집합을 State Machine이라고 한다. 말이 어려운데 간단하게 정리하자면
유한한 State를 정의하고 State를 변경할 수 있는 Event를 정의하여 상태 간에 어떠한 이벤트에 의해 State가 변경되는지 추적할 수 있는 다이어그램이라고 생각하면 된다.
[출처] Microsoft Docs, How NFC Class Works?
State Machine으로서 Generator의 장점을 확인해보고자 한다. 간략한 예제이다.
광고는 간단하게 3가지 상태를 갖는다. INIT
, ACTIVE
, INACTIVE
의 3가지 상태를 갖고 상태를 transition할 수 있는 경우는 다음과 같다고 정의해보자.
이를 Generator를 통한 상태머신으로 만들면 다음과 같다.
// 상태 정의
const INIT = Symbol("INIT");
const ACTIVE = Symbol("ACTIVE");
const INACTIVE = Symbol("INACTIVE");
// event 정의
const END_OF_CONTRACT = Symbol("END_OF_CONTRACT");
const CONTRACT_EXPIRATION = Symbol("CONTRACT_EXPIRATION");
const CONTRACT_EXTENSION = Symbol("CONTRACT_EXTENSION");
const REGISTER = Symbol("REGISTER");
const print = (...args) => console.log(args[0], args[1])
const AdStateMachine = function* () {
let state = INIT;
let transition;
while(true) {
if((state === INIT || state === INACTIVE) && (transition === CONTRACT_EXTENSION || transition === REGISTER)) {
// transition
state = ACTIVE;
}
if(state === ACTIVE && (transition === END_OF_CONTRACT || transition === CONTRACT_EXPIRATION)) {
// transition
state = INACTIVE
}
transition = yield state;
}
}
const adSm = AdStateMachine();
print("InitState: ", adSm.next().value);
print("Register: ", adSm.next(REGISTER).value); // REGISER 이벤트 발생 transition 발생
print("Current State: ", adSm.next().value);
print("END_OF_CONTRACT: ", adSm.next(END_OF_CONTRACT).value); // REGISER 이벤트 발생 transition 발생
print("Current State: ", adSm.next().value);
print("CONTRACT_EXTENSION: ", adSm.next(CONTRACT_EXTENSION).value); // REGISER 이벤트 발생 transition 발생
print("Current State: ", adSm.next().value);
/**
* 결과
*/
// InitState: Symbol(INIT)
// Register: Symbol(ACTIVE)
// Current State: Symbol(ACTIVE)
// END_OF_CONTRACT: Symbol(INACTIVE)
// Current State: Symbol(INACTIVE)
// CONTRACT_EXTENSION: Symbol(ACTIVE)
// Current State: Symbol(ACTIVE)